首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在线程中使用PySide6

在线程中使用PySide6
EN

Stack Overflow用户
提问于 2022-04-19 21:22:03
回答 1查看 128关注 0票数 0

Qt有一个很有前途的SCXML模块。由于PySCXML已经过时,因此没有其他原生PySCXML库,它允许我运行scxml statemachine。这就是我尝试PySide6的原因。

由于我不需要任何Qt,尽管使用了scxml库,所以我考虑在一个单独的线程中运行QCoreApplication,以便让事件循环就在那里。根据文档,QScxmlStateMachine需要一个。

不幸的是,我的start_statemachine()方法没有返回,但是statemachine开始工作。

任何关于如何在线程中启动QScxmlStateMachine的建议都是受欢迎的。

代码语言:javascript
复制
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()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-19 21:52:27

线程目标需要是对将在外部线程中调用的函数的引用,但不是在另一个线程中运行start_statemachine():您实际上正在执行它:

代码语言:javascript
复制
x = threading.Thread(target=start_statemachine('statemachine.scxml'))
                                              ^^^^^^^^^^^^^^^^^^^^^^

您的程序停留在那里,甚至没有创建线程,因为构造函数仍在“等待”start_statemachine()返回,而且由于exec()阻塞,其他任何事情都不会发生。

一个基本的解决方案可以是使用lambda:

代码语言:javascript
复制
x = threading.Thread(target=lambda: start_statemachine('statemachine.scxml'))

但是您需要访问应用程序才能退出它:x.join()什么也不做,因为QCoreApplication事件循环将继续进行,因此有可能创建一个提供对应用程序的引用的基本类:

代码语言:javascript
复制
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()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71931524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档