PyQt - simplest working example of a combobox inside QTableView

Background: I cannot find a full working example of a combobox inside a QTableView. So I wrote this code based on several other more contrived examples out there. The problem is, however, that this example requires you to double-click on the combobox before it becomes enabled, then you have to click again to drop it down. It's not very user-friendly. If I do the non-model/view-thing using QTableWidget, the combobox drops down on the first click.

Question: Can someone look at this and tell me what needs to be done to make it respond just like QTableWidget? Also if there is anything that I'm doing that is unnecessary, please indicate that also. For example, is it absolutely necessary to reference the application style?

import sys
from PyQt4 import QtGui, QtCore

rows = "ABCD"
choices = ['apple', 'orange', 'banana']

class Delegate(QtGui.QItemDelegate):
    def __init__(self, owner, items):
        super(Delegate, self).__init__(owner)
        self.items = items
    def createEditor(self, parent, option, index):
        self.editor = QtGui.QComboBox(parent)
        self.editor.addItems(self.items)
        return self.editor
    def paint(self, painter, option, index):
        value = index.data(QtCore.Qt.DisplayRole).toString()
        style = QtGui.QApplication.style()
        opt = QtGui.QStyleOptionComboBox()
        opt.text = str(value)
        opt.rect = option.rect
        style.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt, painter)
        QtGui.QItemDelegate.paint(self, painter, option, index)
    def setEditorData(self, editor, index):
        value = index.data(QtCore.Qt.DisplayRole).toString()
        num = self.items.index(value)
        editor.setCurrentIndex(num)
    def setModelData(self, editor, model, index):
        value = editor.currentText()
        model.setData(index, QtCore.Qt.DisplayRole, QtCore.QVariant(value))
    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)

class Model(QtCore.QAbstractTableModel):
    def __init__(self):
        super(Model, self).__init__()
        self.table = [[row, choices[0]] for row in rows]
    def rowCount(self, index=QtCore.QModelIndex()):
        return len(self.table)
    def columnCount(self, index=QtCore.QModelIndex()):
        return 2
    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return self.table[index.row()][index.column()]
    def setData(self, index, role, value):
        if role == QtCore.Qt.DisplayRole:
            self.table[index.row()][index.column()] = value

class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.model = Model()
        self.table = QtGui.QTableView()
        self.table.setModel(self.model)
        self.table.setItemDelegateForColumn(1, Delegate(self, ["apple", "orange", "banana"]))
        self.setCentralWidget(self.table)
        self.setWindowTitle('Delegate Test')
        self.show()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    main = Main()
    app.exec_()

Using QTableWiget.setCellWidget

import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
table = QtGui.QTableWidget(1,1)
combobox = QtGui.QComboBox()
combobox.addItem("Combobox item")
table.setCellWidget(0,0, combobox)
table.show()
app.exec()

PyQt, I am trying to display a combo box in my table so that I can set the selected index from This is the simplest example I can come up with to demonstrate the problem. QTableView): """ A simple table to demonstrate the QComboBox delegate. PyQt-simplest working example of a combobox inside QTableView (4) Background: I cannot find a full working example of a combobox inside a QTableView. So I wrote this code based on several other more contrived examples out there.

If you are trying to adjust when the view displays the editor, you need to change the edit trigger as defined in QAbstractItemView. The default is edit on doubleClick, but I think what you are after is QAbstractItemView.CurrentChanged. Set it by calling myView.setEditTrigger()

Pyqt combobox get items, How to list all COM ports in Combobox or Listbox and allow user to select the python - PyQt - simplest working example of a combobox inside QTableView;  combo_box_options = ["Option 1","Option 2","Option 3"] This is the list of values you want your combobox to hold. In this example, there are three options. for t in combo_box_options: combo.addItem(t) self.table.setCellWidget(index,2,combo) This block sets up the combobox, per row, and then adds it to a cell (the last one in this example).

[PyQt] Best way to add combobox into table?, When I insert QSpinBox into QTableWidget, it works well and returns QSpinBox Here's a simple example: > > class Widget(QtWidgets. Is there any way to read >> and change the data in the combobox in tablewidget? Tag: combobox,pyqt,qt4,tableview. I am new to PyQT. I am interested to add a combobox to the each row of tableView. Is it possible in PyQT 4? I know, it is possible in QT5, but not sure about PyQT. Thank you in advance for help. Answer: Does this need to be done using a QTableView or can you do it using a QTableWidget?

This should work:

view = QTreeView()
model = QStandardItemModel(view)
view.setModel(model)

combobox = QComboBox()

child1 = QStandardItem('test1')
child2 = QStandardItem('test2')
child3 = QStandardItem('test3')
model.appendRow([child1, child2, child3])
a = model.index(0, 2)
view.setIndexWidget(a, combobox)

Display tables in PyQt5/PySide2, QTableView with , A simple working example is shown below, which defines a custom model working with a simple nested-list as a data store. We'll go into alternative data  combo_box_options = ["Option 1","Option 2","Option 3"] This is the list of values you want your combobox to hold. In this example, there are three options. for t in combo_box_options: combo.addItem(t) self.table.setCellWidget(index,2,combo) This block sets up the combobox, per row, and then adds it to a cell (the last one in this example).

You can try something like this.

import sys
from PyQt4 import QtGui, QtCore

rows = "ABCD"
choices = ['apple', 'orange', 'banana']

class Delegate(QtGui.QItemDelegate):
    def __init__(self, owner, items):
        super(Delegate, self).__init__(owner)
        self.items = items
    def createEditor(self, parent, option, index):
        self.editor = QtGui.QComboBox(parent)
        self.editor.addItems(self.items)
        return self.editor
    def paint(self, painter, option, index):
        value = index.data(QtCore.Qt.DisplayRole).toString()
        style = QtGui.QApplication.style()
        opt = QtGui.QStyleOptionComboBox()
        opt.text = str(value)
        opt.rect = option.rect
        style.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt, painter)
        QtGui.QItemDelegate.paint(self, painter, option, index)
    def setEditorData(self, editor, index):
        value = index.data(QtCore.Qt.DisplayRole).toString()
        num = self.items.index(value)
        editor.setCurrentIndex(num)
        if index.column() == 1: #just to be sure that we have a QCombobox
            editor.showPopup()
    def setModelData(self, editor, model, index):
        value = editor.currentText()
        model.setData(index, QtCore.Qt.DisplayRole, QtCore.QVariant(value))
    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)

class Model(QtCore.QAbstractTableModel):
    def __init__(self):
        super(Model, self).__init__()
        self.table = [[row, choices[0]] for row in rows]
    def rowCount(self, index=QtCore.QModelIndex()):
        return len(self.table)
    def columnCount(self, index=QtCore.QModelIndex()):
        return 2
    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return self.table[index.row()][index.column()]
    def setData(self, index, role, value):
        if role == QtCore.Qt.DisplayRole:
            self.table[index.row()][index.column()] = value
            return True
        else:
            return False

class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.model = Model()
        self.table = QtGui.QTableView()
        self.table.setModel(self.model)
        self.table.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged) # this is the one that fits best to your request
        self.table.setItemDelegateForColumn(1, Delegate(self, ["apple", "orange", "banana"]))
        self.setCentralWidget(self.table)
        self.setWindowTitle('Delegate Test')
        self.show()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    main = Main()
    app.exec_()

As you can see, I just added a couple of lines to your code. The View manages the "edition" so you must change the edition triggers. Then when you set the delegate data, force the delegate to show the popup from the widget.

Some time ago, I read a blog post on which the author subclassed QAbstractItemView in order to work 'properly' with delegates (edition, navigation, updating data, etc), but I cant find the post :(

Hope it helps.

Access QComboBox inside QTableWidget, For the normal cells inside my table, I am using: Registration is fast, simple and absolutely free so please, join our the QTableWidget, and some of the fields need to have a dropdown menu, Here is an working example. The following are code examples for showing how to use PyQt5.QtWidgets.QTableView().They are from open source Python projects. You can vote up the examples you like or vote down the ones you don't like.

Qt5 Tutorial ModelView with QTableView and QItemDelegate, In this tutorial, we will learn about ModelView QTableView and QItemDelegate. In this example, we'll use Qt Gui application with QDialog: to the user, but provides a simpler framework based on the same principles. *ui; // QStandardItemModel provides a classic // item-based approach to working with the model. Background: I cannot find a full working example of a combobox inside a QTableView. So I wrote this code based on several other more contrived examples out there. The problem is, however, that this

PyQt, Open a Table when a row is selected populating it with the row , I am trying to learn how to build a Simple POS system. or add a button to a cell in the row and open the sub-form with a table, QTableWidget(Dialog) I have renamed everything so you know what you are working on. How can I get for example the comboBoxes to display if product is Maclean price  Using QTableWidget developers can embed tables inside Qt applications. QTableWidget inherits QTableView. Items in a QTableWidget instance are provided by class QTableWidgetItem. Basic Usage Set number of rows and columns

[Solved] QTableView reflected in every tab PyQt, So when I open a new tab I get QTableView in it. Then it will work on the one i just selected and won't reflect result, Can you give us a look at the code (or an example showing the In the short term, the solution to your problem is a simple rewrite of QListView() listView.show() comboBox = QtGui. PyQt: Simplest way to make a CRUD UI for an existing database? PyQt - simplest working example of a combobox inside QTableView. 0.

Comments
  • You may find my answer to this question helpful.
  • Thank you, now I see that the paint override is unnecessary, and I need to openPersistentEditor. But calling openPersistentEditor seems to defeat the purpose of model/view if I need to call that from outside of the model. Plus, it seems inefficient to draw all those comboboxes when you can only operate one at a time. Is there a way to either get rid of the double-click requirement so it appears upon cell selection?
  • You don't need to call it from the model. You can use another object (e.g. your subclassed view or form) to track model changing and invoke editor if necessary. For the second question, connect the selectionChanged signal of the view->selectionModel() to your slot. In this slot open editor in selected cell and close previous editors if necessary.
  • The question asks for a combo-box inside a QTableView, not a QTableWidget.
  • @ekhumoro yes, I saw that but I thought he just wanted a way to get a widget in a table. I'll probably delete this answer.