6

QTreeWidget上的 itemChecked 和 itemUncheсked 信号在哪里?

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 ()

目前我这样解决它:

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)

但这对我来说是一个糟糕的解决方案,因为itemClicked在很多情况下都会发出。它在项目文本上的鼠标左键/右键单击的情况下发出,这是绝对不必要的(我在 self.handleChecked 中有繁重的函数,并且在上下文菜单打开时对它们的不必要调用非常糟糕)。

好吧,我也尝试使用itemChanged

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

但这样一来情况就更糟了!self.handle 函数递归调用自己到无穷大和更远的地方,因为我在 self.handleChecked 中的函数更改了项目数据,并且这个信号一次又一次地发出。另外,我需要仅在项目复选框切换时发出的信号。

有人可以告诉我,我做错了什么吗?

4

2 回答 2

13

为避免在使用itemChanged信号时出现递归问题,请尝试暂时阻塞信号直到处理程序完成:

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)

更新

您问题的另一部分询问仅在检查项目时才发出信号。

一种方法是继承 QTreeWidgetItem 并重新实现它的setData函数:

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))
于 2012-12-01T20:21:48.087 回答
0

要完成@ekhumoro 的答案,并给出更简短的答案(不继承 QTreeWidgetItem):阻止信号:

self.treeWidget.blockSignals(True)
self.treeWidget.blockSignals(False)

并使用

self.treeWidget.itemChanged

to connect to what you want. the signal is used when the data is changed (text inside, checked state, ...) and in your function linked to this signal verify if the treeWidget has changed is checked state.

于 2020-04-23T10:11:41.423 回答