2012-03-11 30 views
3

特定の信号が送信されたときにQTreeWidgetでチェック可能な項目を有効/無効にしたいとします。QTreeViewイベントの項目を有効/無効にする方法は?

次のコードdows動作しない:

model = QStandardItemModel() 
view = QTreeView() 
view.setModel(model) 
rootItem = QStandardItem() 
rootItem = model.invisibleRootItem() 

categoryItem = QStandardItem(item) 
categoryItem.setCheckable(True) 
rootItem.appendRow(categoryItem) 

signalSource.availabilityChanged.connect(categoryItem.setEnabled) 

それはエラーを生成します

TypeError: unhashable type: 'PySide.QtGui.QStandardItem' 

信号/スロットを介しQStandardItemの状態やデータを変更するための解決策はありますか?

+0

完全なトレースバックと 'signalSource'の定義を投稿できますか? – Avaris

答えて

3

connectは呼び出し可能なものを受け入れる必要があるため、PySideのバグのようです(Pyqt4ではサンプルコードが正しく動作します)。

回避策として、ラムダでQStandardItemメソッドをラップしてみてください:

signalSource.availabilityChanged.connect(
    lambda enable: categoryItem.setEnabled(enable)) 

EDIT

は、ループ内の項目を接続するには、デフォルトの引数を使用して、次のように:

for button in buttonList: 
    item = QStandardItem("Test") 
    ... 
    button.toggled.connect(
     lambda enable, item=item: item.setEnabled(enable)) 
+0

ありがとうございます。これは多くの助けとなりました。 @ – leviathan

+0

@leviathan。ループで 'lambda'を使う方法については、私の更新答えを見てください。 – ekhumoro

1

ekhumorosの回答の助けを借りて、私は私の問題を解決する方法を見つけましたが、PySでは醜い回避策のようです送信者を使用して信号を正しく接続することができます。

import sys 
import argparse 
import signal 

#import sip 
#sip.setapi('QString', 2) 
#from PyQt4.QtGui import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QStandardItemModel, QStandardItem, QTreeView 
from PySide.QtGui import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QStandardItemModel, QStandardItem, QTreeView 


class MainWindow(QWidget): 
    def __init__(self, parent=None): 
       QWidget.__init__(self, parent) 

       buttonList = [] 
       for i in xrange(10): 
        button = QPushButton("1") 
        button.setCheckable(True) 
        buttonList.append(button) 

       model = QStandardItemModel() 
       view = QTreeView() 

       view.setModel(model) 

       layout = QVBoxLayout() 
       self.setLayout(layout) 

       buttonLayout = QHBoxLayout() 
       layout.addLayout(buttonLayout) 

       for button in buttonList: 
        buttonLayout.addWidget(button) 

       layout.addWidget(view) 

       rootItem = QStandardItem() 
       rootItem = model.invisibleRootItem() 

       self.itemList = {} 
       for button in buttonList: 
        item = QStandardItem("Test") 
        item.setCheckable(True) 
        rootItem.appendRow(item) 
        self.itemList[button] = item 

        # Works with PyQt4, but not with PySide 
        #button.toggled.connect(item.setEnabled) 
        # Workaround for PySide 
        button.toggled.connect(self.workaround) 

       for button in buttonList: 
        button.setChecked(True) 


      def workaround(self, enable): 
       self.itemList[self.sender()].setEnabled(enable) 


def main(argv): 
    app = QApplication(argv) 
    w = MainWindow() 
    w.show() 
    retcode = app.exec_() 


if __name__ == "__main__": 
    main(sys.argv) 

ラムダ構造を使用してもループでは機能しませんでした。すべての信号を最後の参照と結びつけて、繰り返し処理します。

関連する問題