tags:

views:

91

answers:

2

I've been trying for a couple days to figure out why my QAbstractLisModel won't allow a user to toggle a checkable item in three states. The model returns the Qt.IsTristate and Qt.ItemIsUserCheckable in the flags() method, but when the program runs only Qt.Checked and Qt.Unchecked are toggled on edit.

class cboxModel(QtCore.QAbstractListModel):
    def __init__(self, parent=None):
        super(cboxModel, self).__init__(parent)
        self.cboxes = [
            ['a',0],
            ['b',1],
            ['c',2],
            ['d',0]
        ]

    def rowCount(self,index=QtCore.QModelIndex()):
        return len(self.cboxes)

    def data(self,index,role):
        if not index.isValid: return QtCore.QVariant()
        myname,mystate = self.cboxes[index.row()]
        if role == QtCore.Qt.DisplayRole:
            return QtCore.QVariant(myname)
        if role == QtCore.Qt.CheckStateRole:
            if mystate == 0:
                return QtCore.QVariant(QtCore.Qt.Unchecked)
            elif mystate == 1:
                return QtCore.QVariant(QtCore.Qt.PartiallyChecked)
            elif mystate == 2:
                return QtCore.QVariant(QtCore.Qt.Checked)
        return QtCore.QVariant()

    def setData(self,index,value,role=QtCore.Qt.EditRole):
        if index.isValid():
            self.cboxes[index.row()][1] = value.toInt()[0]            
            self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
                      index, index)
            print self.cboxes
            return True
        return False

    def flags(self,index):
        if not index.isValid():
            return QtCore.Qt.ItemIsEditable
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable |     QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsTristate

You can test it with this,

class MainForm(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

        model = cboxModel(self)

        self.view = QtGui.QListView()
        self.view.setModel(model)

        self.setCentralWidget(self.view)


app = QtGui.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()

and see that only 2 states are available. I'm assuming there's something simple I'm missing. Any ideas? Thanks!

A: 

You may need to create a custom slot on the clicked() signal that cycles through the three states. Generally, tri-state elements are only able to be clicked on and off directly, and are only in the partially checked mode if sub-elements are in different states.

taynaron
A: 

Looks like it's a known issue, check here:

108755 - Qt::ItemIsTristate fails to set checkboxs within a model view to being Tristate

serge_gubenko