JWA
JWA

Reputation: 31

QComboBox in QTreeView?

I'm trying to create a QTreeView that should hold a QComboBox on each row in a certain column so that I can choose the data for a cell from a list of strings. What I would like to do is something like

item = QtGui.QStandardItem(QtGui.QComboBox())

but that is obviously not possible.

This is fairly easy to do in GTK+ toolkit, so I guess it should be possible in Qt4 too. If it is not (easily) possible, what would be an alternative?

Presently, I have no code to present. Could someone give a hint on which direction to go? I'm writing the code in python.

Upvotes: 1

Views: 1268

Answers (1)

JWA
JWA

Reputation: 31

Apparently delegating the editor role is the way to go. After cutting and pasting and editing examples I've found, I have got something working:

import sys
from PyQt4 import QtGui, QtCore

class MyModel(QtGui.QStandardItemModel):
    def __init__(self):
        super(QtGui.QStandardItemModel, self).__init__()
        self.setColumnCount(3)
        self.setHorizontalHeaderLabels(['Col 1', 'Col2 2', 'Col 3'])

    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        item = self.itemFromIndex(index)
        item.setData(value, role=QtCore.Qt.DisplayRole)


class ComboDelegate(QtGui.QItemDelegate):
    def __init__(self, parent):
        QtGui.QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        combo = QtGui.QComboBox(parent)
        combo.addItem('a')
        combo.addItem('b')
        combo.addItem('c')
        combo.addItem('t')
        combo.addItem('w')
        return combo

    def setEditorData(self, editor, index):
        text = index.data().toString()
        index = editor.findText(text)
        editor.setCurrentIndex(index)

    def setModelData(self, editor, model, index):
        model.setData(index, editor.itemText(editor.currentIndex()))

    def updateEditorGeometry(self, editor, option, index):
        print option, option.rect
        editor.setGeometry(option.rect)


def row_clicked(model_index):
    row = model_index.row()
    print model_index.data(0).toString()


if __name__ == '__main__':
    myapp = QtGui.QApplication(sys.argv)
    model = MyModel()
    view = QtGui.QTreeView()
    view.setUniformRowHeights(True)
    view.setModel(model)
    view.setItemDelegateForColumn(1, ComboDelegate(view))
    view.show()
    view.pressed.connect(row_clicked)

    for n in [['q','w','e'],['r','t','y']]:
        item_a = QtGui.QStandardItem(unicode(n[0]))
        item_b = QtGui.QStandardItem(unicode(n[1]))
        item_c = QtGui.QStandardItem(unicode(n[2]))
        model.appendRow([item_a, item_b, item_c])

    for row in range(0, model.rowCount()):
        view.openPersistentEditor(model.index(row, 1))

    myapp.exec_()

Now, the problem is that when I'm using the combo boxes to change the data of the model items, the row heights of the view rows do not match the heights of the combos, until I resize the window. What's wrong?

Upvotes: 1

Related Questions