我想在启动某些操作时向我的GUI添加一个悸动。
这是我的剧本:
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!")
因为这是我第一次使用Thread,所以我找不到什么是错的,哪里错了..
这没有结果,即使我认为我离正确的代码不太远。
我设法让悸动出现但不是在正确的时刻(线程当时没有工作)。
答案 0 :(得分:2)
您的代码存在一个问题,即在主线程中正在执行对os.system()
的调用(可能是长时间运行,因此需要使用throbber)。这会阻止GUI(以及Qt事件循环)。 QMovie
需要一个正常运行的事件循环来正确设置动画。因此,使用您当前的代码,您无法做任何事情来使throbber显示为动画,因为这需要响应式GUI(或更准确地说是响应式事件循环)。
另外,您也不允许直接从线程调用GUI方法。您只能从辅助线程(正如您当前所做的那样)将事件发送回主线程。这意味着您无法将QMovie
卸载到某个帖子。
因此,您需要将对os.system()
的调用卸载到线程中,并在完成后发出信号。该信号可以连接到一个停止悸动的插槽。在启动该主题之前,只需直接调用您现有的startThrobber()
方法即可开始该操作。
这样,当线程处理阻塞所有内容的长时间运行进程时,您的UI仍然保持响应(包括正确显示throbber动画)。
答案 1 :(得分:0)
我没有使用QThread
,而是使用了subprocess
,但效果很好。
我不知道其中的区别,比如一个人是否更好"比另一个,或者如果他们有小的差异等,但它做的工作!