2012-12-01 54 views
4

QTreeWidget上的信号itemChecked和itemUncheсked在哪里?如何在PyQt4中为QTreeWidget实现itemChecked和itemUnchecked信号?

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函数将自己递归地调用到infinity和更远,因为self.handleChecked中的函数会更改项目数据,并且此信号会一次又一次地发出。另外,我需要只在项目复选框切换时发出的信号。

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

+0

的'itemChanged'信号肯定是使用正确的。 “self.handle调用递归地”意味着什么?那究竟是“不可接受的”呢? – ekhumoro

+0

@ekhumoro,我更新了帖子。 –

+0

我已经更新了我的答案,只有当检查的状态发生变化时才发出信号,您可能发现比阻止信号更好。 – ekhumoro

回答

10

为了避免递归问题,使用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) 

UPDATE

你的问题的另一部分被问及只发射信号当一个项目被检查。要做到这一点

一种方法是子类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)) 
+0

有人可以帮助将此翻译成C++吗? – taz

+2

@taz。您需要发布一个新问题:没有人会看到您的评论。 – ekhumoro