2011-05-13 7 views
3

gtk를 사용하여 GUI를 그리는 클래스가 있습니다.PyGTK에서 스레드는 어떻게 사용합니까?

버튼을 클릭하면 일부 외부 프로그램을 실행할 메서드가 호출됩니다.

그러나 GUI가 그 동안 다시 그려지지 않을 수 있습니다.

스레드를 사용하는 것이 해결책 일 수 있습니다. 이 example은 GUI 클래스 외부에 스레드를 생성하고 gtk.main()을 호출하기 전에 시작합니다.

GUI 클래스 외부에서 스레드를 생성하여 버튼 클릭 이벤트를 감지하고 메서드를 호출하는 방법은 무엇입니까?

+0

수정 사항 : 링크의 예에는 GUI 클래스가 없습니다. –

답변

4

외부 프로그램을 실행하기 위해 다른 스레드가 필요하지 않은 경우 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! 
+1

나는 이벤트 기반 루프를 사용하는 것이 가능한 한 스레드를 최대한 피하는 것이라고 덧붙였다. –

관련 문제