2016-06-10 2 views
0

Ich habe eine GUI mit pyside entwickelt und es führt einen Befehl aus, nachdem eine Schaltfläche gedrückt wurde. Der erste Befehl der aufgerufenen Funktion aktualisiert den Status auf "Downloading ..." im text_terminal. Der zweite Befehl startet den eigentlichen Download (eine SQL-Abfrage, die über Pandas und cx_Oracle ausgeführt wird).Unerwartete Reihenfolge der Ausführung - GUI aktualisiert nur, nachdem der Download abgeschlossen ist

Die seltsame Sache ist, dass das text_terminal nur mit dem aktualisiert wird, nachdem der Download abgeschlossen ist. Irgendwelche Vorschläge, was das verursachen kann?

ui.text_terminal.append("Downloading....") 
self.df = dbrs.retrieve(date) 
+1

GUI-Code hat in der Regel eine Ereignisschleife ausgeführt, um Updates zu verarbeiten. – stark

+0

Wie kann ich sicherstellen, dass "Schleife" die letzte Aufgabe abgeschlossen hat, bevor etwas anderes ausgeführt wird? – Nickpick

+0

Wahrscheinlich wird die Ereignisschleife nicht ausgeführt, während Sie Ihren Download ausführen. Wenn Sie möchten, dass eine GUI etwas ausführt, müssen lang andauernde Aufgaben von einem separaten Thread ausgeführt werden. – stark

Antwort

2

Die GUI wird nicht aktualisiert, bis die Neuzeichnungsereignisse verarbeitet werden. Diese werden normalerweise am Anfang einer Ereignisschleife ausgeführt. Wenn Ihre Anwendung mit dem Ausführen von Python-Code beschäftigt ist, wird nicht mit dem nächsten Zyklus der Ereignisschleife fortgefahren, bis dieser Code ausgeführt wird. Der richtige Weg besteht darin, lang andauernde Operationen in einen separaten Thread zu pushen, so dass der Haupt-GUI-Thread nicht gehalten wird und die Ereignisschleife GUI-Update-Ereignisse verarbeiten kann, aber es gibt Möglichkeiten, um sie herumzuhacken.

Sie können die Anwendung einfach anweisen, die Neuzeichnungsereignisse zu verarbeiten.

ui.text_terminal.append("Downloading....") 
QtGui.QApplication.processEvents() 
self.df = dbrs.retrieve(date) 

Rufen Sie diese vor Ihrer retrieve Funktion und es sollte eine Aktualisierung der GUI erzwingen.

Die andere Möglichkeit besteht darin, die Operation einfach auf den nächsten Event-Loop-Zyklus zu schieben, was bedeutet, dass es mindestens 1 Redraw gibt, bevor es ausgeführt wird. Sie können dies mit einem single shot QTimer tun. Dies unterbricht den Fluss Ihrer Funktion, so dass es nur Sinn macht, wenn Sie nach dem Download nichts anderes tun.

def do_retrieve(self, date): 
    self.df = dbrs.retrieve(date) 

ui.text_terminal.append("Downloading....") 
QtCore.QTimer.singleShot(1, lambda: self.do_retrieve(date)) 
+0

der Download buckt immer noch die Benutzeroberfläche, nur einen Moment später. "Es macht also nur Sinn, wenn Sie nach dem Download nichts anderes machen." - Man könnte das "alles andere" in do_retrieve() verschieben. Das Hauptproblem besteht darin, eine synchrone API für den Download zu verwenden, die richtige Lösung wäre jedoch, den Abruf asynchron zu starten und einen Rückruf aufzurufen, wenn er fertig ist. –

Verwandte Themen