Python QSignalTransition子类从未接收到自定义PyQt信号

Python QSignalTransition子类从未接收到自定义PyQt信号,python,python-3.x,pyqt,pyqt5,qstatemachine,Python,Python 3.x,Pyqt,Pyqt5,Qstatemachine,正在尝试学习PyQt5QStateMachine,其转换派生自为PySide编写的QSignalTransition。为了使用PyQt,我刚刚更改了信号的定义,以及它在QSignalTransition初始值设定项中的引用方式。这是完整的代码: from PyQt5.QtCore import QObject, pyqtSignal, QSignalTransition, QCoreApplication, QStateMachine, QState, QFinalState class F

正在尝试学习PyQt5
QStateMachine
,其转换派生自为PySide编写的
QSignalTransition
。为了使用PyQt,我刚刚更改了信号的定义,以及它在
QSignalTransition
初始值设定项中的引用方式。这是完整的代码:

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_())
从PyQt5.QtCore导入QObject、pyqtSignal、QSignalTransition、QCoreApplication、QStateMachine、QState、QFinalState
类阶乘(QObject):
xChanged=pyqtSignal(int)
定义初始化(自):
超级(阶乘,自).\uuuu init\uuuuu()
self.xval=-1
self.facval=1
def getX(自我):
返回self.xval
def setX(自身,x):
如果self.xval==x:
返回
self.xval=x
self.xChanged.emit(x)
x=属性(int、getX、setX)
def getFact(self):
返回自我传真
def setFact(自身、fac):
self.facval=fac
fac=属性(int、getFact、setFact)
类FactorialLoopTransition(QSignalTransition):
定义初始(自我、事实):
super(FactorialLoopTransition,self)。\uuuu init\uuuu(fact.xChanged[int])
事实
def事件测试(自我,e):
如果不是超级(FactorialLoopTransition,self).eventTest(e):
返回错误
返回e.arguments()[0]>1
定义转换(self,e):
x=e.参数()[0]
fac=self.fact.fac
self.fact.fac=x*fac
self.fact.x=x-1
类别FactorialDomainTransition(QSignalTransition):
定义初始(自我、事实):
super(FactorialDoneTransition,self)。\uuuuu init\uuuu(fact.xChanged[int])
事实
def事件测试(自我,e):
如果不是超级(FactorialDoneTransition,self)。事件测试(e):
返回错误
返回e.arguments()[0]该方法需要一个Q_属性,在PySide/PySide2 equals属性的情况下(这与python本机提供的属性不同),在PyQt4/PyQt5的情况下,必须使用该属性,这就是错误的原因,因此解决方案将替换为以下内容:

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) # <---

# ...
来自PyQt5.QtCore导入QObject、pyqtSignal、QSignalTransition、QCoreApplication、QStateMachine、QState、QFinalState、pyqtProperty
类阶乘(QObject):
xChanged=pyqtSignal(int)
定义初始化(自):
超级(阶乘,自).\uuuu init\uuuuu()
self.xval=-1
self.facval=1
def getX(自我):
返回self.xval
def setX(自身,x):
如果self.xval==x:
返回
self.xval=x
self.xChanged.emit(x)

x=pyqtProperty(int,getX,setX)#感谢您的完美解释,这正是解决方案。我不明白为什么这会导致发送类型不正确的事件。@分钟问题是,如果没有传递正确的值,状态机将启动但从未完成,因此从未发出QStateMachine finished信号,因此也没有调用关闭应用程序的app.quit()。实际上,我发现发送的第一个事件不是
SignalEvent
,即使代码是正确的。所以,在修正之前,没有其他事件被发送,因为x的值从未改变。
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) # <---

# ...