2012-12-01 52 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