我正在尝试通过在执行需要一些时间的任务时在活动QMainWindow / QDialog上方显示加载掩码来改善用户体验。我已经设法让它按照我想要的方式工作,除了在执行任务时移动的GIF。如果在任务完成后我打开负载模板,GIF将按原样开始移动。
我的加载掩码类:
from PyQt4 import QtGui, QtCore
from dlgLoading_view import Ui_dlgLoading
class dlgLoading(QtGui.QDialog, Ui_dlgLoading):
def __init__(self,parent):
QtGui.QDialog.__init__(self,parent)
self.setupUi(self)
self.setWindowFlags(QtCore.Qt.WindowFlags(QtCore.Qt.FramelessWindowHint))
self.setGeometry(0, 0, parent.frameGeometry().width(), parent.frameGeometry().height())
self.setStyleSheet("background-color: rgba(255, 255, 255, 100);")
movie = QtGui.QMovie("loader.gif")
self.lblLoader.setMovie(movie)
movie.start()
def showEvent(self, event):
QtGui.qApp.processEvents()
super(dlgLoading, self).showEvent(event)
def setMessage(self,message):
self.lblMessage.setText(message)
Ui_dlgLoading包含两个标签和一些垂直间隔:lblLoader(将包含gif)和lblMessage(如果需要,将包含一条消息)
我使用以下代码创建加载掩码:
loadmask = dlgLoading(self)
loadmask.setMessage('Reading data... Please wait')
loadmask.show()
我认为我需要一些多线程/多处理,但我不能为我的生活找出如何做到这一点。我在某处读到了你可以篡改图形用户界面的线程,所以我需要把繁重的任务转移到那里,但我还是空白。
作为一个简单的例子,让我们说我正在尝试将一个巨大的文件加载到内存中:
file = open(dataFilename, 'r')
self.dataRaw = file.read()
file.close()
我将创建并关闭我的加载掩码对话框。如何在不停止GIF动画的情况下启动文件读取?
GUI用于运行一些繁重的外部exe文件,因此它也可以使用它。
答案 0 :(得分:0)
我最终这样做了:
class runthread(threading.Thread):
def __init__(self, commandline, cwd):
self.stdout = None
self.stderr = None
self.commandline = commandline
self.cwd = cwd
self.finished = False
threading.Thread.__init__(self)
def run(self):
subprocess.call(self.commandline, cwd=self.cwd)
self.finished = True
class command()
def __init__(self):
...
def run():
...
thread = runthread("\"%s\" \"%s\"" % (os.path.join(self.__caller.exefolder, "%s.exe" % self.__cmdtype), self.__name), self.__caller.exeWorkdir)
thread.start()
count = 0
sleeptime = 0.5
maxcount = 60.0/sleeptime
while True:
time.sleep(sleeptime)
QtWidgets.qApp.processEvents()
count += 1
if thread.finished:
break
if count >= maxcount:
results = QtWidgets.QMessageBox.question(self.__caller, "Continue?", "The process is taking longer than expected. Do you want to continue?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
if results == QtWidgets.QMessageBox.Yes:
count == 0
else:
QtWidgets.QMessageBox.warning(self.__caller, "Process stopped", "The process was stopped")
return False
它实际上并没有直接回答我的问题,但它对我有用,所以如果其他人想要做类似的话,我会发布答案。
我通过一个线程调用一个进程(在本例中为Pythons subprocess.call)并跟踪进程实际完成的时间。连续循环定期检查过程是否完成并更新GUI(processEvents - 这是触发GIF更新的原因)。为避免无限循环,我会在一段时间后为用户提供退出选项。