代码之家  ›  专栏  ›  技术社区  ›  Peter

无法从QtGui.QStandardItem发出信号

  •  1
  • Peter  · 技术社区  · 7 年前

    我正在尝试覆盖 QTreeView QtGui 而不是 QtWidgets .

    class QStandardItem(QtGui.QStandardItem):
        someSignal = QtCore.Signal()
        def __init__(self, *args, **kwargs):
            QtGui.QStandardItem.__init__(self, *args, **kwargs)
            self.someSignal.emit()
    
    >>> QStandardItem()
    # AttributeError: 'PySide2.QtCore.Signal' object has no attribute 'emit' # 
    

    以下是我目前的代码仅供参考:

    class QStandardItem(QtGui.QStandardItem):
        checkStateChanged = QtCore.Signal(object)
    
        def __init__(self, *args, **kwargs):
            QtGui.QStandardItem.__init__(self, *args, **kwargs)
    
        def setData(self, data, role):
            if role == QtCore.Qt.CheckStateRole:
                self.checkStateChanged.emit(self)
            QtGui.QStandardItem.setData(self, data, role)
    
    
    class QTreeView(QtWidgets.QTreeView):
        def __init__(self, *args, **kwargs):
            QtWidgets.QTreeView.__init__(self, *args, **kwargs)
    
        #I need to know when to trigger this as it edits other nodes
        def checkStateChanged(self, model_index):
            selected_item = self.model().itemFromIndex(model_index)
            check_state = selected_item.checkState()
    
            #Handle child nodes
            for i in range(selected_item.rowCount()):
                child_item = selected_item.child(i)
                if child_item.isCheckable():
                    child_item.setCheckState(check_state)
    
            #Handle parent nodes
            parent_item = selected_item.parent()
            check_states = {QtCore.Qt.Checked: 0,
                            QtCore.Qt.PartiallyChecked: 1,
                            QtCore.Qt.Unchecked: 2}
            counts = [0, 0, 0]
            if parent_item is not None:
                for i in range(parent_item.rowCount()):
                    child_item = parent_item.child(i)
                    if child_item.isCheckable():
                        counts[check_states[child_item.checkState()]] += 1
                if counts[0] and not counts[1] and not counts[2]:
                    parent_item.setCheckState(QtCore.Qt.Checked)
                elif not counts[0] and not counts[1] and counts[2]:
                    parent_item.setCheckState(QtCore.Qt.Unchecked)
                else:
                    parent_item.setCheckState(QtCore.Qt.PartiallyChecked)
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   eyllanesc    7 年前

    正如您所指出的,只有继承自 QObject 能发出信号, QStandardItem 不是一个 setData() Q标准项目 itemFromIndex() 返回 给予 QModelIndex .

    例子:

    from PySide2 import QtCore, QtGui, QtWidgets
    
    
    class StandardItemModel(QtGui.QStandardItemModel):
        checkStateChanged = QtCore.Signal(QtGui.QStandardItem)
    
        def setData(self, index, value, role=QtCore.Qt.EditRole):
            if role == QtCore.Qt.CheckStateRole:
                last_value = self.data(index, role)
            val = super(StandardItemModel, self).setData(index, value, role)
            if role == QtCore.Qt.CheckStateRole and val:
                current_value = self.data(index, role)
                if last_value != current_value:
                    it = self.itemFromIndex(index)
                    self.checkStateChanged.emit(it)
            return val
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            w = QtWidgets.QTreeView()
    
            model = StandardItemModel(w)
            w.setModel(model)
    
            model.checkStateChanged.connect(self.foo_slot)
    
            for i in range(4):
                top_level = QtGui.QStandardItem("{}".format(i))
                top_level.setCheckable(True)
                model.appendRow(top_level)
                for j in range(5):
                    it = QtGui.QStandardItem("{}-{}".format(i, j))
                    it.setCheckable(True)
                    top_level.appendRow(it)
            w.expandAll()
            self.setCentralWidget(w)
    
        @QtCore.Slot(QtGui.QStandardItem)
        def foo_slot(self, item):
            print(item.text(), item.checkState())
    
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())
    
        2
  •  0
  •   PapaTim68    7 年前

    不是100%确定,但对于Python,为了定义自己的信号,必须使用:

    QtCore.pyqtSignal()
    

    你可能还需要 QtCore.QObject 为了使用信号

    编辑:刚刚看到你在使用pyside,所以放弃了第一个解决方案,但是使用QObject是你的解决方案

    推荐文章