[英]Custom PyQt signal never received by QSignalTransition subclass
Trying to learn PyQt5 QStateMachine
with transitions derived from QSignalTransition
following this example written for PySide.努力学习PyQt5 QStateMachine
与源自过渡QSignalTransition
下面这个例子对于PySide写的。 To use PyQt I just changed the definition of the signal, and the way it is referenced in QSignalTransition
initializer.为了使用 PyQt,我只是更改了信号的定义,以及在QSignalTransition
初始化程序中引用它的方式。 This is the complete code:这是完整的代码:
from PyQt5.QtCore import QObject, pyqtSignal, QSignalTransition, QCoreApplication, QStateMachine, QState, QFinalState
class Factorial(QObject):
xChanged = pyqtSignal(int)
def __init__(self):
super(Factorial, self).__init__()
self.xval = -1
self.facval = 1
def getX(self):
return self.xval
def setX(self, x):
if self.xval == x:
return
self.xval = x
self.xChanged.emit(x)
x = property(int, getX, setX)
def getFact(self):
return self.facval
def setFact(self, fac):
self.facval = fac
fac = property(int, getFact, setFact)
class FactorialLoopTransition(QSignalTransition):
def __init__(self, fact):
super(FactorialLoopTransition, self).__init__(fact.xChanged[int])
self.fact = fact
def eventTest(self, e):
if not super(FactorialLoopTransition, self).eventTest(e):
return False
return e.arguments()[0] > 1
def onTransition(self, e):
x = e.arguments()[0]
fac = self.fact.fac
self.fact.fac = x * fac
self.fact.x = x - 1
class FactorialDoneTransition(QSignalTransition):
def __init__(self, fact):
super(FactorialDoneTransition, self).__init__(fact.xChanged[int])
self.fact = fact
def eventTest(self, e):
if not super(FactorialDoneTransition, self).eventTest(e):
return False
return e.arguments()[0] <= 1
def onTransition(self, e):
print(self.fact.fac)
if __name__ == '__main__':
import sys
app = QCoreApplication(sys.argv)
factorial = Factorial()
machine = QStateMachine()
compute = QState(machine)
compute.assignProperty(factorial, 'fac', 1)
compute.assignProperty(factorial, 'x', 6)
compute.addTransition(FactorialLoopTransition(factorial))
done = QFinalState(machine)
doneTransition = FactorialDoneTransition(factorial)
doneTransition.setTargetState(done)
compute.addTransition(doneTransition)
machine.setInitialState(compute)
machine.finished.connect(app.quit)
machine.start()
sys.exit(app.exec_())
This state machine just compute the factorial of 6 and print it.这个状态机只是计算 6 的阶乘并打印出来。
My problem is, in both transitions, this piece of code:我的问题是,在这两个转换中,这段代码是:
def eventTest(self, e):
if not super(FactorialDoneTransition, self).eventTest(e):
return False
return e.arguments()[0] <= 1
returns False
on the first and only call.第一次也是唯一一次调用时返回False
。 I assume this is because the event passed is not of the proper type, and the superclass returns False
.我认为这是因为传递的事件类型不正确,并且超类返回False
。 With this behavior the transitions are never executed, and the the state machine remains at its initial state.通过这种行为,永远不会执行转换,并且状态机保持在其初始状态。
Can someone explain what is the problem?有人可以解释一下是什么问题吗? Is it my conversion from PySide to PyQt which is wrong?是我从 PySide 到 PyQt 的转换是错误的吗?
The assignProperty()
method expects a Q_PROPERTY that in the case of PySide/PySide2 equals Property (which is different from the property provided by python natively) and in the case of PyQt4/PyQt5 you must use pyqtProperty , and that is the cause of the error so the solution is to replace with the following: assignProperty()
方法需要一个 Q_PROPERTY,在 PySide/PySide2 的情况下等于 Property(这与 python 本身提供的属性不同),在 PyQt4/PyQt5 的情况下,您必须使用pyqtProperty ,这就是导致错误,因此解决方案是替换为以下内容:
from PyQt5.QtCore import QObject, pyqtSignal, QSignalTransition, QCoreApplication, QStateMachine, QState, QFinalState, pyqtProperty
class Factorial(QObject):
xChanged = pyqtSignal(int)
def __init__(self):
super(Factorial, self).__init__()
self.xval = -1
self.facval = 1
def getX(self):
return self.xval
def setX(self, x):
if self.xval == x:
return
self.xval = x
self.xChanged.emit(x)
x = pyqtProperty(int, getX, setX) # <---
def getFact(self):
return self.facval
def setFact(self, fac):
self.facval = fac
fac = pyqtProperty(int, getFact, setFact) # <---
# ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.