首页 > 解决方案 > 不支持 C++ 类型作为 pyqtSignal() 类型参数类型

问题描述

我正在尝试在我的 GUI 中实现状态机(使用 python3.8 和 Qt5(使用 PyQt5 而不是 PySides!))。我遇到的问题是在添加基于事件的转换时。

使用下面的代码,解释器在第 26 行抱怨:

s1.addTransition(self.btn_start, pyqtSignal("clicked()"), s2)
TypeError: C++ type 'clicked()' is not supported as a pyqtSignal() type argument type
import sys
import logging
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QApplication
from PyQt5.QtCore import QStateMachine, QState, QFinalState, pyqtSignal


class TabTest(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.logger = logging.getLogger("TABTEST")

        self.btn_start = QPushButton("START")
        # self.btn_start.clicked.connect(self.btn_start_clicked)

        layout = QVBoxLayout()
        layout.addWidget(self.btn_start)
        self.setLayout(layout)

        machine = QStateMachine()
        s1 = QState()
        s1.assignProperty(self.btn_start, "TEXT", "CLICK ME")

        s2 = QFinalState()
        s1.addTransition(self.btn_start, pyqtSignal("clicked()"), s2)

        machine.addState(s1)
        machine.addState(s2)
        machine.setInitialState(s1)
        machine.start()

    # def btn_start_clicked(self):
    #     self.logger.info("klikked")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = TabTest()
    main_window.show()
    sys.exit(app.exec_())

我之前用谷歌搜索并阅读了stackoverflow,但所有答案都是针对Qt4或正在使用的PySidesQt5和之间有很多变化Qt4。并且PySideshas ,我在isPySides.QtCore.SIGNAL中找到了等价物,但似乎无法正常工作。PyQt5PyQt5.QtCore.pyqtSignal

标签: pythonpython-3.xpyqt5qt-signalsqstatemachine

解决方案


您的代码有 3 个错误:

  • QStateMachine 是一个局部变量,将立即销毁以防止观察到所需的行为,因为有两种解决方案:设置父级(更改为QStateMachine(self))或使其成为类的成员(将所有更改machineself.machine)。

  • 如果要分配属性,则必须尊重名称,在这种情况下,属性是“文本”而不​​是“文本”。

  • 在 PyQt5 中,您必须传递信号,即obj.foo_signal,在您的情况下self.btn_start.clicked

考虑到上述情况,解决方案是:

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

        self.btn_start = QPushButton("START")

        layout = QVBoxLayout(self)
        layout.addWidget(self.btn_start)

        machine = QStateMachine(self)

        s1 = QState()
        s1.assignProperty(self.btn_start, "text", "CLICK ME")

        s2 = QFinalState()

        s1.addTransition(self.btn_start.clicked, s2)

        # Check if QFinalState was entered
        machine.finished.connect(lambda: print("finished"))

        machine.addState(s1)
        machine.addState(s2)
        machine.setInitialState(s1)
        machine.start()

推荐阅读