2017-07-05 5 views
0

Ich habe eine Schaltfläche, die eine Schleife ausführt und das Fenster entsprechend aktualisiert. Ich möchte einen weiteren "Pause" -Button, der diese Schleife unterbricht, aber es scheint nicht so, als könnte ich das tun, während der Loop läuft. Vielleicht ist Threading die Lösung (ich habe versucht GLib.timeout_add_seconds ohne Erfolg) - was ist der einfachste Weg, um das zu funktionieren? Ich habe meine fehlerhaften Code angehängt:Wie pausiere ich eine Schleife mit einer Schaltfläche in PyGObject?

import sys 
from time import sleep 
import gi 
gi.require_version("Gtk", "3.0") 
from gi.repository import Gtk 

class LoopButton(Gtk.Box): 

    def __init__(self, GUI): 
     Gtk.Box.__init__(self) 

     self.GUI = GUI 
     self.set_border_width(10) 
     self.message = "1" 

     button = Gtk.Button.new_with_label("Run") 
     button.connect("clicked", self.on_click) 
     self.pack_start(button, True, True, 0) 

    def on_click(self, widget): 
     msg = int(self.message) 
     while self.GUI.is_paused == False: 
      self.GUI.restart_window(str(msg)) 
      msg += 1 
      while Gtk.events_pending(): 
       Gtk.main_iteration() 
      sleep(1) 
     self.GUI.is_paused = True 

class PauseButton(Gtk.Box): 
    def __init__(self, GUI): 
     Gtk.Box.__init__(self) 

     self.GUI = GUI 
     self.set_border_width(10) 

     button = Gtk.Button.new_with_label("Pause") 
     button.connect("clicked", self.on_click) 
     self.pack_start(button, True, True, 0) 

    def on_click(self, widget): 
     self.GUI.is_paused = True 


class GUI: 

    def __init__(self): 
     self.is_paused = False 
     self.win = Gtk.Window() 
     self.window_grid = Gtk.Grid() 
     self.box = Gtk.Box(spacing=10) 
     self.label = Gtk.Label("Default label") 
     self.win.connect("delete-event", Gtk.main_quit) 
     self.start_window() 

    def start_window(self): 
     self.box.pack_start(LoopButton(self), True, True, 0) 
     self.box.pack_start(PauseButton(self), True, True, 0) 
     self.window_grid.add(self.box) 
     self.window_grid.add(self.label) 
     self.win.add(self.window_grid) 
     self.win.show_all() 

    def restart_window(self, label="Default label"): 
     self.window_grid.destroy() 
     self.window_grid = Gtk.Grid() 
     self.box = Gtk.Box(spacing=10) 
     self.label = Gtk.Label(label) 
     self.start_window() 

def main(): 
    app = GUI() 
    Gtk.main() 

if __name__ == "__main__": 
    sys.exit(main()) 
+0

Ist das die gleiche Frage wie https://stackoverflow.com/questions/44916094/why-cant-i-have-a-loop-in-the-onclick-function-in-pygobject? – jku

+1

Was wird Ihr tatsächlicher Code in der Schleife tun? Die Antwort hängt davon ab. – andlabs

+0

@jku Nein, ist es nicht. Es ist sehr ähnlich und ich habe diesen Code geändert, aber ich habe gefragt, wie man die Schleife pausiert, etwas, was die andere Frage nicht getan hat. –

Antwort

0

Je nachdem, was Sie wirklich tun es in der Schleife Details notwendig, mehr sein kann, aber unten ist ein Beispiel dafür, wie Looping normalerweise in Glib/Gtk vermieden wird. Die Vorbehalte dieser Methode sind: A) Eine Iteration muss schnell genug sein, um UI-Aktualisierungen nicht zu beeinträchtigen (höchstens einige Millisekunden). B) Das Timing ist nicht exakt: Die Timeout-Funktion wird möglicherweise 2 Sekunden nach dem vorherigen Anruf nicht genau aufgerufen.

import gi 
from gi.repository import GLib 

class GUI: 
    def __init__(self): 
     # initialize the UI here... 

     # setup updates every two seconds 
     GLib.timeout_add_seconds(2, self.timeout_update) 

    def timeout_update(self): 
     # update your widgets here 
     print ("Updating UI now...") 

     # yes, we want to be called again 
     return True 
+0

Perfekt - das funktioniert jetzt. Ich habe auch versucht, timeout_add_seconds vorher zu verwenden, aber ich gab nicht True zurück, was es nicht richtig laufen ließ. –

Verwandte Themen