How to implement itemChecked and itemUnchecked signals for QTreeWidget in PyQt4?

白昼怎懂夜的黑 提交于 2019-11-28 01:34:19

问题


Where are the signals itemChecked and itemUncheсked on the QTreeWidget?

Qt Signals: (quote from PyQt4 QTreeWidget documentation page)

void currentItemChanged (QTreeWidgetItem *,QTreeWidgetItem *)
void itemActivated (QTreeWidgetItem *,int)
void itemChanged (QTreeWidgetItem *,int)
void itemClicked (QTreeWidgetItem *,int)
void itemCollapsed (QTreeWidgetItem *)
void itemDoubleClicked (QTreeWidgetItem *,int)
void itemEntered (QTreeWidgetItem *,int)
void itemExpanded (QTreeWidgetItem *)
void itemPressed (QTreeWidgetItem *,int)
void itemSelectionChanged ()

At current moment I solved it like this:

self.treeWidget.itemClicked.connect (self.handle)

def handle (item, column): 
    print 'emitted!', item.text(column)
    if item.checkState(column) == QtCore.Qt.Checked:
        # there are a lot of my functions inside which work with item data
        self.handleChecked(item, column)
    elif item.checkState(column) == QtCore.Qt.Unchecked:
        self.handleUnchecked(item, column)

But it's a bad solution for me, because itemClicked emitted in a really lot of cases. It emitted in the case of Left/Right Mouse Clicks on the item text, which is absolutely unnecessary (I have heavy functions within self.handleChecked, and unnecessary calls of them on the context menu opening are pretty lousy).

Well, I also tried to use itemChanged:

self.treeWidget.itemChanged.connect (self.handle)

but this way situation is even worse! self.handle function calls himself recursively to infinity and beyond, because my functions within self.handleChecked change item data and this signal emits again and again. Also, I need signal which emits only on item checkbox toggling.

Can someone tell me, what I'm doing wrong?


回答1:


To avoid problems with recursion when using the itemChanged signal, try temporarily blocking signals until the handler has completed:

def handle(self, item, column):
    self.treeWidget.blockSignals(True)
    if item.checkState(column) == QtCore.Qt.Checked:
        self.handleChecked(item, column)
    elif item.checkState(column) == QtCore.Qt.Unchecked:
        self.handleUnchecked(item, column)
    self.treeWidget.blockSignals(False)

UPDATE

The other part of your question asked about emitting a signal only when an item is checked.

One way to do this would be to subclass QTreeWidgetItem and reimplement it's setData function:

class TreeWidgetItem(QtGui.QTreeWidgetItem):
    def setData(self, column, role, value):
        state = self.checkState(column)
        QtGui.QTreeWidgetItem.setData(self, column, role, value)
        if (role == QtCore.Qt.CheckStateRole and
            state != self.checkState(column)):
            treewidget = self.treeWidget()
            if treewidget is not None:
                treewidget.itemChecked.emit(self, column)

class Window(QtGui.QTreeWidget):
    itemChecked = QtCore.pyqtSignal(object, int)

    def __init__(self, rows, columns):
        QtGui.QTreeWidget.__init__(self)
        self.itemChecked.connect(self.handleItemChecked)

    def handleItemChecked(self, item, column):
        print 'ItemChecked', int(item.checkState(column))


来源:https://stackoverflow.com/questions/13662020/how-to-implement-itemchecked-and-itemunchecked-signals-for-qtreewidget-in-pyqt4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!