【问题标题】:How to implement itemChecked and itemUnchecked signals for QTreeWidget in PyQt4?如何在 PyQt4 中为 QTreeWidget 实现 itemChecked 和 itemUnchecked 信号?
【发布时间】:2012-11-19 15:58:30
【问题描述】:

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 中的函数更改了项目数据,并且这个信号一次又一次地发出。另外,我需要仅在项目复选框切换时发出的信号。

谁能告诉我,我做错了什么?

【问题讨论】:

  • itemChanged 信号绝对是正确的选择。 “self.handle 递归调用”是什么意思?究竟什么是“不可接受的”?
  • @ekhumoro,我更新了帖子。
  • 我已经用一种可能的解决方案更新了我的答案,仅在检查状态发生变化时才发出信号,您可能会发现这比阻塞信号更好。

标签: qt pyqt pyqt4 signals-slots qtreewidget


【解决方案1】:

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

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

【讨论】:

  • 有人可以帮忙翻译成 C++ 吗?
  • @taz。您需要发布一个新问题:其他人不会看到您的评论。
【解决方案2】:

要完成@ekhumoro 的回答, 并给出一个更简短的答案(不继承 QTreeWidgetItem): 屏蔽信号:

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

并使用

self.treeWidget.itemChanged

连接到您想要的。 数据更改时使用信号(内部文本,检查状态,...) 并在链接到此信号的函数中验证 treeWidget 是否已更改为选中状态。

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 2023-03-17
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多