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

2024-10-01 00:28:01 发布

您现在位置:Python中文网/ 问答频道 /正文

尝试学习PyQt5QStateMachine,其转换来自为PySide编写的this example之后的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_())

这个状态机只是计算6的阶乘并打印出来。你知道吗

我的问题是,在这两种转换中,这段代码:

def eventTest(self, e):
    if not super(FactorialDoneTransition, self).eventTest(e):
        return False
    return e.arguments()[0] <= 1

在第一次也是唯一一次调用时返回False。我假设这是因为传递的事件的类型不正确,并且超类返回False。有了这种行为,就永远不会执行转换,状态机也会保持其初始状态。你知道吗

有人能解释一下是什么问题吗?是我从PySide到PyQt的转换错了吗?你知道吗


Tags: selffalsereturnifinitdefmachineint
1条回答
网友
1楼 · 发布于 2024-10-01 00:28:01

^{}方法需要一个Q\u属性,在PySide/PySide2 equals属性的情况下(这与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) # < -

# ...

相关问题 更多 >