In PyGTK, how do I use a thread?
I have a class that draws a GUI, using gtk.
Clicking a button will call a method that will run some external program开发者_如何学运维s.
But the GUI may not redraw in the meantime.
One solution may be to use threads. This example creates a thread outside the GUI class and starts it before calling gtk.main().
How do I make a thread outside the GUI class detect a button click event and call the appropriate method?
You don't need another thread to launch an external program, you can use Gtk's idle loop. Here's some pieces of program I wrote to do just that. It had to read the stdout of the program to show parts of it on the GUI as well, so I left that in there. The variable "job_aborted" is tied to an "Abort" button, that allows for early termination.
class MyWindow ...
# here's the button's callback
def on_simulate(self, button):
self.job_aborted = False
args = self.makeargs() # returns a list of command-line args, first is program
gobject.idle_add(self.job_monitor(args).next)
def job_monitor(self, args):
self.state_running() # disable some window controls
yield True # allow the UI to refresh
# set non-block stdout from the child process
p = subprocess.Popen(args, stdout=subprocess.PIPE)
fd = p.stdout.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
while True:
if self.job_aborted:
os.kill(p.pid, signal.SIGTERM)
break
poll = p.poll()
if poll is not None:
break
try:
line = p.stdout.readline()
if line:
line = line.strip()
# update display
except IOError:
pass
yield True
self.state_ready() # re-enable controls
if self.job_aborted:
# user aborted
else:
# success!
精彩评论