Search code examples
qtcheckboxpyqtqlistwidgetqlistwidgetitem

Partially check QListWidget item by mouse click (tristate)


Qt 4.8. I need some items in my list to have 3 states. So i add the following code:

item = QtGui.QListWidgetItem("Hello there")
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable |
    QtCore.Qt.ItemIsTristate)
item.setCheckState(QtCore.Qt.PartiallyChecked)

An item is successfully set to partially checked state on its creation, but further mouse clicks switch it between checked/unchecked states.


Solution

  • 'Cause we cannot make QListWidget iterate through 3 states automatically in Qt 4.8 (ItemIsUserTristate flag was added in Qt 5.5), we'll do it manually:

    CHECKSTATE_ROLE = 32
    
    def lstFiles_itemChanged(self, item):  # slot
        if item.flags() & QtCore.Qt.ItemIsTristate:
            if item.checkState() == QtCore.Qt.Checked and \
                            item.data(CHECKSTATE_ROLE) == QtCore.Qt.Unchecked:
                item.setCheckState(QtCore.Qt.PartiallyChecked)
            item.setData(CHECKSTATE_ROLE, item.checkState())
    
    item = QtGui.QListWidgetItem("Buenas noches")
    if this_item_needs_tristate:
        item.setFlags(item.flags() | QtCore.Qt.ItemIsTristate)
        state = QtCore.Qt.PartiallyChecked
    else:
        state = QtCore.Qt.Checked
    item.setCheckState(state)
    item.setData(CHECKSTATE_ROLE, item.checkState())
    

    An item remembers its previous check state in a user data element so we can change states appropriately on itemChanged.