Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无法从QtGui.QStandardItem发出信号_Python_Pyside2 - Fatal编程技术网

Python 无法从QtGui.QStandardItem发出信号

Python 无法从QtGui.QStandardItem发出信号,python,pyside2,Python,Pyside2,如果复选框被修改,我试图覆盖QTreeView以处理调整父项和子项。然而,我无法发出信号,我不确定这是否是因为我正在尝试子类化QtGui,而不是qtwidget 以下是将触发错误的代码: class QStandardItem(QtGui.QStandardItem): someSignal = QtCore.Signal() def __init__(self, *args, **kwargs): QtGui.QStandardItem.__init__(sel

如果复选框被修改,我试图覆盖
QTreeView
以处理调整父项和子项。然而,我无法发出信号,我不确定这是否是因为我正在尝试子类化
QtGui
,而不是
qtwidget

以下是将触发错误的代码:

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)

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

QtCore.pyqtSignal()
此外,为了使用信号,您可能还需要输入
QtCore.QObject


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

正如您所指出的,只有继承自
QObject
的类才能发出信号,
QStandardItem
不是
QObject
,因此产生了这个问题。适当的选择是使用QStandardItemModel,为此,我们覆盖
setData()
方法,并建立一个逻辑来验证状态是否已更改,然后使用
itemFromIndex()
方法发出
QStandardItem
,该方法返回
QStandardItem
给定的
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_())

不继承自
QObject
,因此不能有与之关联的信号。是否有可供
QTreeView
使用的替代项目类?我目前正在使用
QStandardItemModel
构建一个嵌套树,其中包含
QStandardItem
。谢谢,它是Pyside2(即Qt5),旧式信号不再存在。谢谢,我必须同时修复其他一些东西,但我会尝试在之后立即将其与我的代码连接:)