Python 将QThread用于throber

Python 将QThread用于throber,python,user-interface,pyqt,qthread,throbber,Python,User Interface,Pyqt,Qthread,Throbber,当启动某些操作时,我想在GUI中添加一个throbber 这是我的剧本: class StartTask(QtCore.QThread): taskStarted = pyqtSignal() def run(self): self.taskStarted.emit() class StopTask(QtCore.QThread): taskStopped = pyqtSignal() def run(self): self.ta

当启动某些操作时,我想在GUI中添加一个throbber

这是我的剧本:

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!")
因为这是我第一次使用线程,所以我找不到哪里出了问题

这不会产生任何结果,尽管我认为我离正确的代码不太远


我已设法使throbber出现,但出现的时间不正确(线程当时不工作)。

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

另外,也不允许从线程直接调用GUI方法。您只能将事件从辅助线程发射回主线程(正如您当前所做的那样)。这意味着您不能将
QMovie
卸载到线程


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


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

我没有使用
QThread
,而是使用了运行良好的
子进程。

虽然我不知道有什么不同,比如一个比另一个好,或者他们之间有什么小的差异等等,但它确实起作用了

为什么要尝试使用线程?那里似乎没有什么东西需要一根线。您创建的线程在启动时只发出一个信号,就是这样(线程结束)。线程用于长时间运行的后台任务,这似乎不是您在这里要做的。好的。那我怎么用这个滴管呢?因为它在脚本运行时未设置为启用,所以它仅在脚本完成运行时启用。我以为有一种特殊的方式来做这件事?哦,是的,我没有想过这样做!谢谢,我会更正我的代码!!我试过了,但还是有同样的问题。throbber不会在我调用线程之前开始,而且,throbber不会停止(即使有movie.stop()命令)…@guy16发布新问题可能会更容易,因为您正在使用不同的方法演示新问题。“此信号可以连接到停止跳动的插槽。在启动线程之前,只需直接调用现有的startThrobber()方法来开始throbber。“这就是我遇到麻烦的地方。我无法同时让这两种方法都起作用,要么是跳动者会开始但不会停止,要么是相反。因为在线程中,我有subprocess.Popen,然后有一个停止throbber的信号,它同时执行这两个操作。。hh在不使用计时器的情况下,如何使信号等待发出?@guy16您正在执行的命令正常运行需要多长时间?(如果从命令行运行,则称为)