Как включить / отключить элемент в базе событий QTreeView? - PullRequest
3 голосов
/ 11 марта 2012

Я хочу включить / отключить проверяемый элемент в QTreeWidget при отправке определенного сигнала.

Следующий код не работает:

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 через сигнал / слот?

Ответы [ 2 ]

3 голосов
/ 12 марта 2012

Это похоже на ошибку в PySide, так как connect должен принимать любой вызываемый объект (пример кода работает правильно в 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))
1 голос
/ 14 марта 2012

С помощью ответа ekhumoros я нашел способ решить мою проблему, но это кажется уродливым обходным путем в PySide, используя отправителя для правильного подключения сигнала.

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)

Простое использование лямбда-конструкции не сработало в цикле. Он просто соединяет весь сигнал с последней ссылкой для итерации.

...