将 QThread 用于 throbber [英] Using QThread for a throbber

查看:35
本文介绍了将 QThread 用于 throbber的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在启动某些操作时向我的 GUI 添加一个 throbber.

I would like to add a throbber to my GUI when some actions are launched.

这是我的脚本:

class StartTask(QtCore.QThread):
    taskStarted = pyqtSignal()
    def run(self):
        self.taskStarted.emit()

class StopTask(QtCore.QThread):
    taskStopped = pyqtSignal()
    def run(self):
        self.taskStopped.emit()

class Projet(object):

    def __init__(self):
        self.movie = '' # throbber
        self.startTask = StartTask()
        self.startTask.taskStarted.connect(self.startThrobber)
        self.stopTask = StopTask()
        self.stopTask.taskStopped.connect(self.stopThrobber)

    def startThrobber(self):
        # set up the movie screen on a label
        self.movie_screen = QLabel()
        # expand and center the label
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.movie_screen)
        ui.throbberTab2.setLayout(main_layout)
        # use an animated gif file you have in the working folder
        byteF = QByteArray()
        movie = QMovie("D:\Various\Images\loader.gif", byteF)
        movie.setCacheMode(QMovie.CacheAll)
        movie.setSpeed(100)
        self.movie_screen.setMovie(movie)
        movie.start()

        return movie

    def stopThrobber(self):
        movie1 = self.startThrobber()
        movie1.stop()

    def goAction(self):
        if ui.chkbox.isChecked():
            self.startTask.taskStarted.connect(self.startThrobber)
            os.system(r'..........') # script launched
            self.stopTask.taskStopped.connect(self.stopThrobber)
            QMessageBox.information(self.popup(), "Information", "It works!")

由于这是我第一次使用线程,所以我找不到问题所在以及问题所在..

Since it's the first time I'm using a Thread, I can't find what's wrong and where it is wrong..

这没有给出任何结果,即使我认为我离正确的代码并不太远.

This gives no result, even though i think i'm not too far away from the correct code.

我已经设法让跳动者出现,但不是在正确的时间(当时线程不工作).

I've managed to make the throbber appear but not at the correct moment (the thread was not working then).

推荐答案

您的代码有一个问题,即对 os.system() 的调用(这可能是长时间运行,因此需要a throbber) 正在主线程中执行.这会阻止 GUI(和 Qt 事件循环).QMovie 需要一个功能正常的事件循环才能正确动画.因此,使用您当前的代码,您无法使抖动显示为动画,因为这需要响应式 GUI(或更准确地说是响应式事件循环).

Your code has a problem in that the call to os.system() (which is presumably long running, hence the need for a throbber) is being executed in the main thread. This blocks the GUI (and the Qt event loop). QMovie requires a functioning event loop to animate correctly. So with your current code, there is nothing you can do to make the throbber appear animated, as that requires a responsive GUI (or more precisely a responsive event loop).

顺便说一句,您也不允许直接从线程调用 GUI 方法.您只能将事件从辅助线程发送回主线程(正如您目前所做的那样).这意味着您无法QMovie 卸载到线程.

As an aside, you are also not allowed to directly call GUI methods from a thread. You can only emit events back to the main thread from a secondary thread (as you are currently doing). This means you cannot offload the QMovie to a thread.

因此,您需要将对 os.system() 的调用卸载到线程中,并在完成后发出信号.该信号可以连接到停止颤动的插槽.在启动线程之前,只需直接调用现有的 startThrobber() 方法即可启动 throbber.

So instead, you need to offload the call to os.system() into a thread, and emit a signal when it is done. This signal can be connected to a slot which stops the throbber. Immediately before launching the thread, just directly call your existing startThrobber() method to begin the throbber.

这样,当线程处理阻塞一切的长时间运行的进程时,您的 UI 保持响应(包括正确显示跳动动画).

This way, your UI remains responsive (including correctly showing the throbber animation) while the thread deals with the long running process that is blocking everything up.

这篇关于将 QThread 用于 throbber的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆