Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find specific Qt.ItemFlag occurrence into custom Qt.ItemFlags instance in PyQt?

Tags:

qt

pyqt

pyqt4

I have a QTreeWidget with QTreeWidgetItems. Method QTreeWidgetItem.flags() returns me Qt.ItemFlags instance.

The Qt.ItemFlags type is a typedef for QFlags. It stores an OR combination of ItemFlag values.

Well, assume now that I have one of my QTreeWidgetItems and I need to find out — is it checkable or not? Other words, I need to find occurrence ItemFlag (for my case, it's Qt.ItemIsUserCheckable) in Qt.ItemFlags instance.

How to do it?

Here's a simple and tidy example that you can modify (the interested part marked by comment lines):

import sys
from PyQt4 import QtCore, QtGui

class Window(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.treeWidget = QtGui.QTreeWidget()
        self.treeWidget.setHeaderHidden(True)
        self.addItems(self.treeWidget.invisibleRootItem())
        self.treeWidget.itemClicked.connect (self.handleClicked)
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.treeWidget)
        self.setLayout(layout)

    def addItems(self, parent):
        column = 0

        clients_item = QtGui.QTreeWidgetItem(parent, ['Clients'])
        clients_item.setData(column, QtCore.Qt.UserRole, 'data Clients')
        clients_item.setExpanded(True)

        item_1 = QtGui.QTreeWidgetItem(clients_item, ['Item 1'])
        item_1.setData(column, QtCore.Qt.UserRole, 'data Item 1')
        item_1.setCheckState(column, QtCore.Qt.Unchecked)

        item_2 = QtGui.QTreeWidgetItem(clients_item, ['Item 2'])
        item_2.setData(column, QtCore.Qt.UserRole, 'data Item 2')
        item_2.setCheckState(column, QtCore.Qt.Unchecked)

    def handleClicked(self, item, column):
        if item.checkState(column) == QtCore.Qt.Checked:
            print "checked", item, item.text(column)
        if item.checkState(column) == QtCore.Qt.Unchecked:
            print "NOT checked", item, item.text(column)

        # this part doesn't work ===============================
        # begin of part
        flags = item.flags()
        if QtCore.Qt.ItemIsUserCheckable in flags:
            print "is checkable", item, item.text(column)
        else:
            print "is NOT checkable", item, item.text(column)
        # end of part ==========================================    

if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
like image 695
Bruno Gelb Avatar asked Nov 28 '12 23:11

Bruno Gelb


1 Answers

Like many of the "flags" and "attributes" in Qt, ItemFlags uses bit masks to combine multiple options into a single value. This can be tested using bitwise operators.

Here is how you would check if the item is checkable:

flags = item.flags()
if flags & QtCore.Qt.ItemIsUserCheckable:
    print "is checkable", item, item.text(column)

Bitwise Masking

It works like this:

Qt.NoItemFlags          0   It does not have any properties set.
Qt.ItemIsSelectable     1   It can be selected.
Qt.ItemIsEditable       2   It can be edited.
Qt.ItemIsDragEnabled    4   It can be dragged.
Qt.ItemIsDropEnabled    8   It can be used as a drop target.
Qt.ItemIsUserCheckable  16  It can be checked or unchecked by the user.
Qt.ItemIsEnabled        32  The user can interact with the item.
Qt.ItemIsTristate       64  The item is checkable with three separate states.

So the value will be some combination of these values. Lets say it is Selectable, Editable, and enabled. For simplicity I will just use the numeric values instead of the flags. We combine them with a logical OR:

flags = 1 | 2 | 32
# 35

And to test the presence of a value we use a logical AND:

# is it editable?
flags & 2
# 2 # would evaluate to True

# is it checkable?
flags & 16
# 0 # would evaluate to False

You could also toggle the flags state in the maks using an XOR operation.

# toggle off the editable flag
flags ^= 2
# toggle on the editable flag
flags ^= 2
like image 61
jdi Avatar answered Oct 17 '22 13:10

jdi