Skip to content Skip to sidebar Skip to footer

Pygtk: Asynchronous Output Implemented With Io_add_watch Blocks When Printing Large Output Dataset

I'm writing a GTK+ GUI program with a python command line emulator. My python command line is implemented as a gtk.TextView, which can be used to output results of prints (and to r

Solution 1:

The external process is blocking the UI while using os.read, you should spawn the process using glib.spawn_async and use a IOChannel to read the input something like:

from gi.repository import Gtk, GLib

classMySpawned(Gtk.Window):
    def__init__(self):
        Gtk.Window.__init__(self)

        vb = Gtk.VBox(False, 5)
        self.tw = Gtk.TextView()
        bt = Gtk.Button('Run')
        bt.connect('clicked', self.process)

        vb.pack_start(self.tw, True, True, 0)
        vb.pack_start(bt, False, False, 0)

        self.add(vb)
        self.set_size_request(200, 300)
        self.connect('delete-event', Gtk.main_quit)
        self.show_all()

    defrun(self):
        Gtk.main()

    defprocess(self, widget, data=None):
        params = ['python', '-h']

        defwrite_to_textview(io, condition):
            print condition
            if condition is GLib.IO_IN:
               line = io.readline()
               self.tw.props.buffer.insert_at_cursor(line)
               returnTrueelif condition is GLib.IO_HUP|GLib.IO_IN:
                GLib.source_remove(self.source_id)
                returnFalse

        self.source_id = None

        pid, stdin, stdout, stderr = GLib.spawn_async(params,
                                        flags=GLib.SpawnFlags.SEARCH_PATH,                                       
                                        standard_output=True)

        io = GLib.IOChannel(stdout)

        self.source_id = io.add_watch(GLib.IO_IN|GLib.IO_HUP,
                                 write_to_textview,
                                 priority=GLib.PRIORITY_HIGH)
if __name__ == '__main__':
    s = MySpawned()
    s.run()

There are like a gazillion threads out there telling you that you could use threads or other stuff, please don't do that, the above example will not block you UI even on a long process and the output will be printed on the textview, works on windows too (but it will open an ugly console window until a bug in GLib will get fixed).

Post a Comment for "Pygtk: Asynchronous Output Implemented With Io_add_watch Blocks When Printing Large Output Dataset"