0

I'm developing a simple application with PyGTK. I have a button which runs a subprocess in ubuntu when it clicked. I want to change status bar once exactly after the button clicked, and once when the subprocess finished. But at the moment it doesn't work fine, because it waits for subprocess to be finished, and then only changes the status bar to "Done". My code is something like this now:

def on_button_clicked(self, widget):
        self.statusBar.push(1, "Doing the subprocess...")

        command = '...'

        print subprocess.call(command,shell=True)
           ...    
        self.statusBar.push(1, "Done!")

I thought I can change the status bar in another function and then call a function to do the rest, but it didn't work (and it sounds silly!). How should I change my code to show "Doing the subprocess..." status while the command is running in background?

sheshkovsky
  • 1,302
  • 3
  • 18
  • 41
  • 1
    It might be illustrative to take a look at [this](http://stackoverflow.com/questions/8583975/stop-pygtk-gui-from-locking-up-during-long-running-process) SO post as an example of how to let the subprocess run outside of the main UI thread. – TML Sep 24 '14 at 21:36

1 Answers1

2

As you figured, subprocess.call() blocks until the command finishes. What you want to do is run the subprocess call in another thread, and then, once the call is done, update the status bar from the thread.

def _do_subproc(command, bar):
    subprocess.call(command, shell=True)
    glib.idle_add(bar.push, 1, "Done!") # call bar.push in the main GUI thread

def on_button_clicked(self, widget):
    self.statusBar.push(1, "Doing the subprocess...")
    command = '...'
    threading.Thread(target=lambda: _do_subproc(command, self.statusBar)).start()

You'll probably want to gray out the button to prevent the user from spam-clicking it.

Claudiu
  • 224,032
  • 165
  • 485
  • 680