6

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 関数は、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)

アップデート

質問の他の部分では、アイテムがチェックされたときにのみ信号を発することについて尋ねました。

これを行う 1 つの方法は、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 に答える