Qt有一个很有前途的SCXML模块。由于PySCXML已经过时,因此没有其他原生PySCXML库,它允许我运行scxml statemachine。这就是我尝试PySide6的原因。
由于我不需要任何Qt,尽管使用了scxml库,所以我考虑在一个单独的线程中运行QCoreApplication,以便让事件循环就在那里。根据文档,QScxmlStateMachine需要一个。
不幸的是,我的start_statemachine()方法没有返回,但是statemachine开始工作。
任何关于如何在线程中启动QScxmlStateMachine的建议都是受欢迎的。
from PySide6.QtCore import QCoreApplication, QObject
from PySide6.QtScxml import QScxmlStateMachine
from PySide6.QtCore import QTimer
import threading
def start_statemachine(filename):
app = QCoreApplication()
mysm = MyStateMachine(filename)
mysm.start_sm()
app.exec()
class MyStateMachine(QObject):
def __init__(self, filename):
super(MyStateMachine, self).__init__()
self.sm = QScxmlStateMachine.fromFile(filename)
self.counter = 0
self.timer = QTimer()
self.timer.setInterval(2000)
self.timer.timeout.connect(self.recurring_timer)
self.timer.start()
def start_sm(self):
print('starting statemachine')
self.sm.setRunning(True)
def recurring_timer(self):
print(self.sm.activeStateNames())
self.counter += 1
print("Counter: %d" % self.counter)
print('statemachine running status: ' + str(self.sm.isRunning()))
if __name__ == '__main__':
x = threading.Thread(target=start_statemachine('statemachine.scxml'))
x.start() #won't be reached
while True:
pass #do something else
x.join()发布于 2022-04-19 21:52:27
线程目标需要是对将在外部线程中调用的函数的引用,但不是在另一个线程中运行start_statemachine():您实际上正在执行它:
x = threading.Thread(target=start_statemachine('statemachine.scxml'))
^^^^^^^^^^^^^^^^^^^^^^您的程序停留在那里,甚至没有创建线程,因为构造函数仍在“等待”start_statemachine()返回,而且由于exec()阻塞,其他任何事情都不会发生。
一个基本的解决方案可以是使用lambda:
x = threading.Thread(target=lambda: start_statemachine('statemachine.scxml'))但是您需要访问应用程序才能退出它:x.join()什么也不做,因为QCoreApplication事件循环将继续进行,因此有可能创建一个提供对应用程序的引用的基本类:
class StateMachineWrapper:
app = None
def __init__(self, filename):
self.filename = filename
def start(self):
self.app = QCoreApplication([])
mysm = MyStateMachine(self.filename)
mysm.start_sm()
self.app.exec()
# ...
if __name__ == '__main__':
statemachine = StateMachineWrapper('statemachine.scxml')
x = threading.Thread(target=statemachine.start)
x.start()
while True:
pass #do something else
if statemachine.app:
statemachine.app.quit()
x.join()https://stackoverflow.com/questions/71931524
复制相似问题