2016-08-09 6 views
2

Ich versuche, die Benutzererfahrung zu verbessern, indem ich eine Lastmaske über dem aktiven QMainWindow/QDialog zeige, wenn Aufgaben ausgeführt werden, die einige Zeit benötigen. Ich habe es geschafft, es so zu arbeiten, wie ich es will, außer einem beweglichen GIF, wenn er die Aufgabe durchführt. Wenn ich die Lade-Maske nach Beendigung der Aufgabe belasse, beginnt die GIF-Datei so zu laufen, wie sie sollte.Behalten Sie die GIF-Animation bei, während Sie Berechnungen durchführen

Meine Klasse für die Last-Maske:

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) 

Die Ui_dlgLoading enthält zwei Etiketten und einige vertikale Abstandshalter: lblLoader (die gif enthalten) und lblMessage (eine Nachricht enthalten, wenn erforderlich)

I die Last Maske mit diesem Code erstellen:

loadmask = dlgLoading(self) 
loadmask.setMessage('Reading data... Please wait') 
loadmask.show() 

ich dachte, ich Multithreading/Multiprozessing benötigt, aber ich kann nicht für das Leben von mir herauszufinden, wie es zu tun. Ich habe irgendwo gelesen, dass Sie die Threads der GUIs nicht manipulieren können, also müsste ich stattdessen die schwere Aufgabe dorthin verschieben, aber ich bin immer noch leer.

Als einfaches Beispiel, sagen wir, ich bin versucht, eine große Datei in den Speicher zu laden:

file = open(dataFilename, 'r') 
self.dataRaw = file.read() 
file.close() 

Around, dass ich schaffen würde und meine Last Maske Dialog schließen. Wie starte ich die Datei lesen, ohne die GIF-Animation zu stoppen?

Die GUI ist für das Ausführen einiger schwerer externer exe-Dateien gedacht, also sollte es auch damit arbeiten.

Antwort

0

ich am Ende tue dies:

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 

Es ist direkt eigentlich meine Frage nicht beantwortet, aber es funktionierte für mich, so dass ich bin Entsendung die Antwort, wenn andere ähnlich etwas tun will.

Ich rufe einen Prozess (in diesem Fall Pythons subprocess.call) durch einen Thread und verfolgen, wenn der Prozess tatsächlich abgeschlossen ist. Eine kontinuierliche Schleife überprüft regelmäßig, ob der Prozess abgeschlossen ist und aktualisiert die GUI (processEvents - dies ist der Auslöser für die Aktualisierung des GIF). Um eine Endlosschleife zu vermeiden, biete ich dem Benutzer eine Option zum Beenden nach einiger Zeit an.

Verwandte Themen