How To Do Background Task In Gtk3-python?
Solution 1:
You didn't actually start the thread, you only instantiated an object that can be used to start it. A full solution requires a careful separation of responsibilities between your GUI thread and your worker thread(s). What you want to do is the following:
Do your heavy calculation in the separate thread, spawned and joined by the GUI code. The calculation should not spawn its own threads, nor does it need to be aware of threads (except for being thread-safe, of course).
When the thread is done, use
gobject.idle_add()
to tell the GUI that the progress indicator can be withdrawn. (gobject.idle_add
is about the only GTK function that is safe to call from another thread.)
With such a setup, the GUI remains fully responsive and progress bar updated no matter what the calculation does, and the GUI thread is guaranteed to notice when the calculation finishes. Two additional points regarding your current code:
Instantiate
threading.Thread
instead of inheriting from it. That way you don't need to bother with implementingrun()
. In both cases you have to callthread.start()
, though, to start off the thread.Don't call
threads_enter()
andthreads_leave()
, unless you really know what you are doing. Just remember that as long as you call all your GTK functions from a single thread (the same thread in which you initialized GTK), you'll be fine.
Here is proof-of-concept code that implements the above suggestions:
def working1(self):
self.label.set_text('working1')
self.work_thread = threading.Thread(self.run_thread)
self.running = True
gobject.timeout_add(200, self.update_progress)
self.work_thread.start()
# the GUI thread now returns to the mainloop
# this will get periodically called in the GUI thread
def update_progress(self):
if self.running:
self.progressbar.pulse() # or set_fraction, etc.
return self.running
# this will get run in a separate thread
def run_thread(self):
Process.heavyworks1() # or however you're starting your calculation
gobject.idle_add(self.stop_progress)
# this will get run in the GUI thread when the worker thread is done
def stop_progress(self):
self.running = False
self.work_thread.join()
self.label.set_text('idle')
Solution 2:
As you suggested you need to start another thread for this. Usually threading in python is pretty straightforward but it can get tricky with GUIs.
This should be of help: Python. Doing some work on background with Gtk GUI
Post a Comment for "How To Do Background Task In Gtk3-python?"