我有一個繪製GUI的類,使用gtk。在PyGTK中,如何使用線程?
點擊一個按鈕會調用一個方法,該方法將運行一些外部的 程序。
但在此期間GUI可能不會重新繪製。
一個解決方案可能是使用線程。這個example在GUI類外創建線程 ,並在調用gtk.main()之前啓動它。
如何在GUI類外部檢測按鈕單擊事件並調用 適當的方法?
我有一個繪製GUI的類,使用gtk。在PyGTK中,如何使用線程?
點擊一個按鈕會調用一個方法,該方法將運行一些外部的 程序。
但在此期間GUI可能不會重新繪製。
一個解決方案可能是使用線程。這個example在GUI類外創建線程 ,並在調用gtk.main()之前啓動它。
如何在GUI類外部檢測按鈕單擊事件並調用 適當的方法?
你不需要另一個線程來啓動外部程序,你可以使用Gtk的空閒循環。以下是我寫的一些程序。它必須讀取程序的標準輸出以在GUI上顯示它的一部分,所以我把它留在那裏。變量「job_aborted」綁定到「Abort」按鈕,可以提前終止。
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!
我會補充說,使用基於事件的循環的重點主要是儘可能避免線程。 – 2011-05-13 20:48:51
更正:鏈接中的示例沒有GUI類。 – 2011-05-13 19:32:54