[pygtk] Non-blocking subprocess.Popen stop GUI

Bou Baris boubaris at gmail.com
Mon Aug 31 23:27:25 WST 2009


SOLVED ! :-)

1) I've tried to use gobject.io_add_watch() and pty without success.
It looks to block reading.
2) using select() is fine
3) using thread is fine. It's the first time that I use Threads and in
my previously code I've not used GTK thread_init() , thread_enter()
and thread_leave()

Now the code works fine.

This is my test code running fine:

------------------- test-thread.py ----------------
#!/usr/bin/env python

import threading,re,subprocess,os,fcntl,select

import pygtk
pygtk.require('2.0')
import gtk

# initialize GTK threading system
gtk.gdk.threads_init()

class MyThread(threading.Thread):
    def __init__(self, progressbar):
        self.pbar = progressbar
        threading.Thread.__init__(self)

    def run(self):

        # se progressbar to 0%
        gtk.gdk.threads_enter()
        self.pbar.set_fraction(0.0)
        self.pbar.set_text("0%")
        gtk.gdk.threads_leave()

        command=[ 'mkvextract', \
                'tracks', \
                '/home/dummy/test/video.mkv', \
                '2:_temp_dts.dts' ]

        proc=subprocess.Popen(command,stdout=subprocess.PIPE)

        outfile=proc.stdout
        outfd=outfile.fileno()
        file_flags = fcntl.fcntl(outfd, fcntl.F_GETFL)
        fcntl.fcntl(outfd, fcntl.F_SETFL, file_flags | os.O_NDELAY)

        while True:
            ready = select.select([outfd],[],[]) # wait for input
            if outfd in ready[0]:
                outchunk = outfile.read()
                if outchunk == '':
                    break
            select.select([],[],[],.1) # give a little time for buffers to fill

            # extract percentages from string "Progress: n%"
            perc =
re.compile("Progress:\s+(\d+)",re.IGNORECASE).findall(outchunk)

            if len(perc) > 0:
                perc = perc[len(perc)-1]
                completed = int(perc) / 100.00
                # show progress bar
                gtk.gdk.threads_enter()
                self.pbar.set_fraction(completed)
                self.pbar.set_text(str(perc) + '%')
                gtk.gdk.threads_leave()

        err = proc.wait()

        return True

def QUITGTK(arg):
    th.stop = True
    gtk.main_quit()

window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.resize(800,600)
pbar = gtk.ProgressBar()
window.add(pbar)
window.show_all()

window.connect('destroy', QUITGTK)

th = MyThread(pbar)
th.start()

gtk.main()

--------------------- end -------------------


More information about the pygtk mailing list