在线程中使用Pyside6
QT有一个有希望的SCXML模块。由于PYSCXML已过时,因此没有其他本机Python SCXML库,它使我可以运行SCXML statemachine。这就是为什么我尝试pyside6。
由于尽管有SCXML库,但我不需要任何QT,因此我考虑过在单独的线程中运行QCoreApplication,以便将事件循环放在那里。 根据文档,QSCXMLSTATATEMACHINE需要一个。
不幸的是,我的start_statemachine()
方法不会返回,但是statemachine开始工作。
欢迎有关如何在线程中启动QSCXMLSTATATEMACHINE的任何建议。
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()
Qt has a promising SCXML module. Since PySCXML is obsolete, there is no other native python scxml library, which lets me run a scxml statemachine. That's why I try PySide6.
Since I don't need any Qt despite of the scxml library, I thought about running the QCoreApplication in a seperate thread, in order to have the event-loop right there.
According to the documentation QScxmlStateMachine needs one.
Unfortunately my start_statemachine()
method doesn't return, but the statemachine starts working.
Any advice on how to start a QScxmlStateMachine in a thread is welcomed.
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
线程目标需要是参考 to在外部线程中会调用的函数,但是您在另一个线程中未运行
start_statemachine()
实际将其执行到位:您的程序被在内粘住,甚至没有创建线程,因为构造函数仍在“等待”
start_statemachine()
返回,并且由于exec()
正在阻止,没有其他事情发生。一个基本的解决方案可能是使用lambda:
但是您需要访问该应用程序才能退出它:
x.join()
不会无能为力,因为qcoreApplication事件循环将继续前进,因此有可能创建一个基本类,以提供对应用程序的参考:The thread target needs to be a reference to a function that will be called in the external thread, but you're not running
start_statemachine()
in another thread: you're actually executing it in place:Your program is stuck there, no thread is even created because the constructor is still "waiting" for
start_statemachine()
to return, and sinceexec()
is blocking, nothing else happens.A basic solution could be to use a lambda:
But you'll need access to the application in order to be able to quit it:
x.join()
won't do nothing, because the QCoreApplication event loop will keep going, so a possibility is to create a basic class that provides a reference to the application: