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"