import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject as gobject import time from multiprocessing import Process, Value, Lock, Pool, Queue import threading gobject.threads_init() class Listener(gobject.GObject): __gsignals__ = { 'updated' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_FLOAT, gobject.TYPE_STRING)), 'finished': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()) } def __init__(self, queue): gobject.GObject.__init__(self) self.queue = queue def go(self): print("Listener has started") while True: # Listen for results on the queue and process them accordingly data = self.queue.get() # Check if finished if data[1]=="finished": print("Listener is finishing.") self.emit("finished") return else: self.emit('updated', data[0], data[1]) gobject.type_register(Listener) class Worker(): def __init__(self, queue): self.queue = queue def go(self): print("The worker has started doing some work (counting from 0 to 9)") for i in range(2542): proportion = (float(i+1))/2542 self.queue.put((proportion, "working...")) time.sleep(0.01) self.queue.put((1.0, "finished")) print("The worker has finished.") class Counter(object): def __init__(self, initval=0.0): self.val = Value('d', initval) self.lock = Lock() def increment(self): with self.lock: self.val.value += 1/2542 print(self.val.value) def value(self): with self.lock: return self.val.value class MyWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title = 'Hello World') #self.val = 0 self.process = None self.box = Gtk.Box(spacing=6) self.add(self.box) self.button1 = Gtk.Button(label = 'Hello') self.button1.connect('clicked', self.go) self.box.pack_start(self.button1, True, True, 0) self.button2 = Gtk.Button(label = 'Goodbye') self.button2.connect('clicked', self.on_button2_clicked) self.box.pack_start(self.button2, True, True, 0) self.pbar = Gtk.ProgressBar() self.pbar.set_fraction(0.0) self.box.pack_start(self.pbar, True, True, 0) def callbackDisplay(self, obj, fraction, text, data=None): self.pbar.set_fraction(fraction) self.pbar.set_text(text) def callbackFinished(self, obj, data=None): if self.process==None: raise RuntimeError("No worker process started") print("all done; joining worker process") self.process.join() self.process = None self.pbar.set_fraction(1.0) self.pbar.set_text("done") print('Goodbye') Gtk.main_quit() def go(self, widget, data=None): if self.process!=None: return print("Creating shared Queue") queue = Queue() print("Creating Worker") worker = Worker(queue) print("Creating Listener") listener = Listener(queue) listener.connect("updated",self.callbackDisplay) listener.connect("finished",self.callbackFinished) print("Starting Worker") self.process = Process(target=worker.go, args=()) self.process.start() print("Starting Listener") thread = threading.Thread(target=listener.go, args=()) thread.start() #def on_button1_clicked(self, widget): #print('Hello') #procs = [Process(target=self.func, args=(counter,)) for i in range(10)] #for p in procs: p.start() #for p in procs: p.join() #p = Pool(2) #p.map(self.func, range(2542)) #print (counter.value()) #while counter.val.value <10: #self.update_pbar(self.pbar) #print('Goodbye') #Gtk.main_quit() def on_button2_clicked(self, widget): print('Goodbye') Gtk.main_quit() #def update_pbar(self, widget, value): #self.val += 0.1 #self.pbar.set_fraction(value) #time.sleep(0.5) #while Gtk.events_pending(): #Gtk.main_iteration() #def func(self, data): #for i in range(2542): #time.sleep(0.01) #counter.increment() #while counter.value() <1: #self.update_pbar(self.pbar, counter.value()) #counter = Counter(0.0) win = MyWindow() win.connect('delete-event', Gtk.main_quit) win.show_all() Gtk.main()