Search code examples
pythongtkpygobject

Using Gtk.spinner with a long time function


I am trying to get working a gtk.spinner using Pygobject in python. The main thing is that I use this element to show the user that a long time action is in progress. The problem is that the spinner stops when doing the function.

the code is here:

.....
def create_image(self,spinner):
    ....
    spinner.start()
    # Heavy function
    spinner.stop()
.....

And this doesn't works. I would accept some help, thanks!


Solution

  • Your heavy function needs to occasionally let the GUI process accumulated events. For example, you can occasionally run:

    while gtk.events_pending():
        gtk.main_iteration()
    

    Another option is for the heavy function to run in a separate thread, leaving the main thread to process the events and spin the spinner. In that case, you will need to redesign your create_image function to be asynchronous. For example:

    def create_image(self, spinner, finishcb):
        spinner.start()
    
        def thread_run():
            # call heavy here
            heavy_ret = heavy()
            gobject.idle_add(cleanup, heavy_ret)
    
        def cleanup(heavy_ret):
            spinner.stop()
            t.join()
            finishcb(heavy_ret)
    
        # start "heavy" in a separate thread and immediately
        # return to mainloop
        t = threading.Thread(thread_run)
        t.start()
    

    Now, instead of calling create_image, you need to pass it a callback that will be called when the image is ready. I.e., instead of:

    image = self.create_image(spinner)
    

    you write:

    self.create_image(spinner, self.store_created_image)