不支持 C++ 类型作为 pyqtSignal() 类型参数类型
C++ type is not supported as a pyqtSignal() type argument type
我正在尝试在我的 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_())
我之前用谷歌搜索并阅读了 Whosebug,但所有答案都是针对 Qt4
或正在使用 PySides
。 Qt5
和 Qt4
之间有很多变化。
PySides
有 PySides.QtCore.SIGNAL
,我发现 PyQt5
中的等效项是 PyQt5.QtCore.pyqtSignal
,但似乎无法正常工作。
您的代码有 3 个错误:
QStateMachine 是一个局部变量,它将立即被销毁以防止观察到所需的行为,因为有 2 个解决方案:设置父级(更改为 QStateMachine(self)
)或创建它class的成员(将所有 machine
更改为 self.machine
)。
如果要分配 属性 则必须尊重名称,在这种情况下 属性 是 "text" 而不是 "TEXT" .
在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(<b>self</b>)
s1 = QState()
s1.assignProperty(self.btn_start, <b>"text"</b>, "CLICK ME")
s2 = QFinalState()
s1.addTransition(<b>self.btn_start.clicked</b>, s2)
# Check if QFinalState was entered
machine.finished.connect(lambda: print("finished"))
machine.addState(s1)
machine.addState(s2)
machine.setInitialState(s1)
machine.start()
我正在尝试在我的 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_())
我之前用谷歌搜索并阅读了 Whosebug,但所有答案都是针对 Qt4
或正在使用 PySides
。 Qt5
和 Qt4
之间有很多变化。
PySides
有 PySides.QtCore.SIGNAL
,我发现 PyQt5
中的等效项是 PyQt5.QtCore.pyqtSignal
,但似乎无法正常工作。
您的代码有 3 个错误:
QStateMachine 是一个局部变量,它将立即被销毁以防止观察到所需的行为,因为有 2 个解决方案:设置父级(更改为
QStateMachine(self)
)或创建它class的成员(将所有machine
更改为self.machine
)。如果要分配 属性 则必须尊重名称,在这种情况下 属性 是 "text" 而不是 "TEXT" .
在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(<b>self</b>)
s1 = QState()
s1.assignProperty(self.btn_start, <b>"text"</b>, "CLICK ME")
s2 = QFinalState()
s1.addTransition(<b>self.btn_start.clicked</b>, s2)
# Check if QFinalState was entered
machine.finished.connect(lambda: print("finished"))
machine.addState(s1)
machine.addState(s2)
machine.setInitialState(s1)
machine.start()