pyside6 qthread仍然冷冻主gui

发布于 2025-02-10 05:59:58 字数 1456 浏览 4 评论 0原文

我目前正在尝试在Pyside6 GUI应用程序中实现一些线程功能。我遵循了一个教程尝试开始的教程(链接是在这里),我似乎无法使它起作用。尽管该教程使用PYQT而非Pyside,但类和结构仍然相似,并且似乎确实在另一个线程上启动。尽管如此,它仍然冻结了主GUI,当它实际上面对用户时,这是不足的。

这是我的代码的示例:

class Worker(QObject):
    finished = Signal(str)
    progress = Signal(int)

    def run(self, file):
        """Long-running task." that calls a separate class for computation""
        b = SeparateClass()
        b.doComputation()
        
        self.finished.emit()
class DataPlotting(QMainWindow):
    def __init__(self):
        self.thread = QThread()
        self.worker = Worker()
        self.report_builder = QPushButton('Call class that threads')
        self.report_builder.setEnabled(False)
        self.report_builder.clicked.connect(self.qthread_test)
    
    def qthread_test(self):
        file = 'some_file.txt'

        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.run(file))
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)
        self.thread.start()
        return

这确实完成了工人班级中的工作并吐出所需的结果,但它冻结了GUI。我不确定自己在做什么错,因为这种方法是建议防止GUIS进行重大计算的建议。

有什么我直截了当的东西吗?还是我以错误的方式进行操作?感谢任何帮助或指导

I am currently trying to implement some threading functionality in my PySide6 GUI application. I followed a tutorial to try to get started (link is here), and I cannot seem to get it to work. Although that tutorial uses PyQt not PySide, the classes and structure is still similar, and it does seem to launch on another thread. Still though, it freezes the main GUI, which is not desired when this actually faces users.

Here is a sample of my code:

class Worker(QObject):
    finished = Signal(str)
    progress = Signal(int)

    def run(self, file):
        """Long-running task." that calls a separate class for computation""
        b = SeparateClass()
        b.doComputation()
        
        self.finished.emit()
class DataPlotting(QMainWindow):
    def __init__(self):
        self.thread = QThread()
        self.worker = Worker()
        self.report_builder = QPushButton('Call class that threads')
        self.report_builder.setEnabled(False)
        self.report_builder.clicked.connect(self.qthread_test)
    
    def qthread_test(self):
        file = 'some_file.txt'

        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.run(file))
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)
        self.thread.start()
        return

This does accomplish the work that is in the Worker class and spit out the desired results, but it freezes the GUI. I am not really sure what I am doing wrong, as this approach is what has been suggested to prevent freezing GUIs for heavy computation.

Is there something that I am straight up missing? Or am I going about this the wrong way? Any help or guidance is appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜空下最亮的亮点 2025-02-17 05:59:58

我假设您在__ Init __ Init __ Init __ qmainwindowqObject的子类中拨打适当的电话。

当您的代码执行self.thread.started.connect(self.worker.run(file))时,这是,作为thread.started信号的连接插槽。而不是将文件路径作为参数传递,您可以将其分配给Worker实例,并在执行过程中从self中获取路径。

例如,您可以尝试这样的事情:

class Worker(QObject):
    finished = Signal(str)
    progress = Signal(int)

    def run(self):
        """Long-running task." that calls a separate class for computation"""
        file = self.some_file
        b = SeparateClass()
        b.doComputation()
        
        self.finished.emit()
class DataPlotting(QMainWindow):
    def __init__(self):
        self.report_builder = QPushButton('Call class that threads')
        self.report_builder.setEnabled(False)
        self.report_builder.clicked.connect(self.qthread_test)
        self.threads = []
    
    def qthread_test(self):
        worker = Worker()
        thread = QThread()
        worker.some_file = 'some_file.txt'
        worker.moveToThread(thread)
        thread.started.connect(worker.run)
        worker.finished.connect(thread.quit)
        worker.finished.connect(worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.start()
        self.threads.append(thread)
        return

I am assuming that you make the appropriate calls to the super class during __init__ for your subclasses of QMainWindow and the QObject.

When your code executes self.thread.started.connect(self.worker.run(file)) that line it runs the function self.worker.run(file) immediately and assigns the result of that function, which is None, as the connected slot to the thread.started signal. Instead of passing the file path as a parameter you can assign it to the worker instance and have the run method grab the path from self during execution.

For example you can try something like this:

class Worker(QObject):
    finished = Signal(str)
    progress = Signal(int)

    def run(self):
        """Long-running task." that calls a separate class for computation"""
        file = self.some_file
        b = SeparateClass()
        b.doComputation()
        
        self.finished.emit()
class DataPlotting(QMainWindow):
    def __init__(self):
        self.report_builder = QPushButton('Call class that threads')
        self.report_builder.setEnabled(False)
        self.report_builder.clicked.connect(self.qthread_test)
        self.threads = []
    
    def qthread_test(self):
        worker = Worker()
        thread = QThread()
        worker.some_file = 'some_file.txt'
        worker.moveToThread(thread)
        thread.started.connect(worker.run)
        worker.finished.connect(thread.quit)
        worker.finished.connect(worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.start()
        self.threads.append(thread)
        return

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文