2012-02-14 6 views
1

그래서 트위터를 얻기 위해 GUI를 만들고 있습니다. 신호를 받고 텍스트 뷰를 변경하는 이벤트 상자를 만들었습니다. 멀티 프로세싱을 사용하여 텍스트 뷰를 변경했지만 변경되지 않았습니다. 창 크기를 변경하려고했습니다. 그러나 아무것도 바뀌지 않습니다. textview의 textbuffer를 가져올 수는 있지만 변경할 수는 없습니다.다른 프로세스에서 textview를 수정하는 방법은 무엇입니까?

import pygtk 
pygtk.require('2.0') 
import gtk 
from multiprocessing import Process 

class multi: 
    def __init__(self): 
     self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     self.window.set_size_request(800,400) 
     self.window.set_title("Twitter Box") 
     self.window.set_border_width(4) 
     self.window.connect("destroy", self.close_application) 

     self.vbox1 = gtk.EventBox() 
     self.vbox1.set_size_request(750,450) 
     self.vbox1.connect('leave_notify_event',self.go_multi) 
     self.window.add(self.vbox1) 
     self.vbox1.show() 

     self.tweetview = gtk.TextView() 
     self.tweetbuffer = self.tweetview.get_buffer() 
     self.tweetbuffer.set_text('Why not working?') 
     self.vbox1.add(self.tweetview) 
     self.tweetview.show() 

     self.window.show() 

    def close_application(self, widget): 
     gtk.main_quit() 

    def go_multi(self, widget, data=None): 
     p = Process(target = self.change_textview) 
     p.start() 
     p.join() 

    def change_textview(self): 
     print 'changing text' 
     startiter = self.tweetbuffer.get_start_iter() 
     enditer = self.tweetbuffer.get_end_iter() 
     text = self.tweetbuffer.get_text(startiter, enditer) 
     print text 
     if text: 
      self.tweetbuffer.set_text('Changed....') 
     else: 
      self.tweetbuffer.set_text('') 
     return 

def main(): 
    multi() 
    gtk.main() 

if __name__ == '__main__': 
    main() 

나는 트윗을 얻기 위해 GUI를 만들고 있습니다. 때로는 연결 속도가 느리고 GUI가 정지되어 타임 라인을 검색하는 데 시간이 오래 걸리는 경우가 있습니다. 그래서 저는 프로세스를 생성하고 타임 라인을 가져오고 트윗 버퍼를 설정할 것이라고 생각했습니다. 하지만 트위터 버퍼에 텍스트를 설정할 수 없습니다.

답변

2

을 내가하지 완전히 inderstand이 할 이유 :

def go_multi(self, widget, data=None): 
    p = Process(target = self.change_textview) 
    p.start() 
    p.join() 

을 왜냐하면 그것이 작동해야하는 원격 가능성에서도, 당신은 기본적으로 change_textview 함수를 호출하고 프로세스가 끝나기를 기다리고 있기 때문입니다.

이 문제를 해결했는데, 다중 처리가 필요 없다고 생각합니다. 대신에 GUI 멀티 스레딩을 만드십시오.

처음에는 Gtk 멀티 스레드를 약간 까다로 만들 수 있지만 어려운 작업은 아닙니다.

  1. 업데이트 GLib.idle_add 사용하여 위젯 [here]를 설명 무슨
  2. 을 (또는 GObject.idle_add를, 나는 완전히 그들이 동일하지 않은 이유를 종종 이해하지 않음) 또는 다음과 같습니다
    당신은 이렇게 두 가지 방법이있다. 어느 그것은 기본적으로 말한다 :

    • 전화하면 전에 다음과 같은 방법이 Gtk.main() 전화 :

      Gdk.threads_enter() 
      # your code here 
      Gdk.threads_leave() 
      
    • : 스레드에서

      GObject.threads_init() 
      Gdk.threads_init() 
      
    • 을,로는 GTK 위젯을 업데이트하는 코드를 둘러싸고

+0

감사합니다. 그것은 나를 많이 돕고 있습니다. 한 번 멀티 스레딩을 시도했지만 아주 잘 작동하지 않았습니다. 그래서, 나는 mutliprocessing를 시도했다. 이제 멀티 스레딩을 할 것입니다. – Froyo

+0

@Froyo : 내 대답을 수락하고/또는 최대 득표하겠습니까? : D –

+0

고마워요! 지금은 잘 작동하고 있습니다! – Froyo

2

무엇이 보이기 전에 렌더링 이벤트를 처리하려면 메인 루프를 실행해야합니다.

또한 GTK 함수를 두 번째 스레드에서 호출하면 안됩니다. 당신이 시작하는 데

이 읽기 ​​: 여기 Multi-threaded GTK applications – Part 1: Misconceptions

을 그리고는 PyGTK이 지식을 적용하는 방법입니다 : Threads on PyGTK

0

답을 찾은 후에도 계속 그런 식으로 진행하려면
면책 조항 :
이 답변의 유용성을 알 수 없습니다.
설명 :
논리를 사용하려고했습니다. 또한 Queue을 가져 와서 프로세스간에 데이터를 공유했습니다.나는 내가 보았을 때 그것이 필요하다고 생각한다 documentation. 아래 코드 샘플에서 다른 정보를 찾을 수 있습니다.

import pygtk 
pygtk.require('2.0') 
import gtk 
from multiprocessing import Process, Queue 

class multi: 
    def __init__(self): 
     self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     self.window.set_size_request(800,400) 
     self.window.set_title("Twitter Box") 
     self.window.set_border_width(4) 
     self.window.connect("destroy", self.close_application) 

     self.vbox1 = gtk.EventBox() 
     self.vbox1.set_size_request(750,450) 
     self.vbox1.connect('leave_notify_event',self.go_multi) 
     self.window.add(self.vbox1) 
     self.vbox1.show() 
     self.tweetview = gtk.TextView() 
     self.tweetbuffer = self.tweetview.get_buffer() 
     self.tweetbuffer.set_text('Why not working?') 
     self.vbox1.add(self.tweetview) 
     self.tweetview.show() 

     self.window.show() 

    def close_application(self, widget): 
     gtk.main_quit() 

    def go_multi(self, widget, data=None): 
     q = Queue() 
     p = Process(target = self.change_textview, args=(q,)) 
     p.start() 
     self.tweetbuffer.set_text(q.get()) 
     p.join() 

    def change_textview(self, q): 
     print 'changing text' 
     startiter = self.tweetbuffer.get_start_iter() 
     enditer = self.tweetbuffer.get_end_iter() 
     text = self.tweetbuffer.get_text(startiter, enditer) 
     print text 
     if text: 
      q.put(('Changed....')) 
     else: 
      q.put(('')) 
def main(): 
    multi() 
    gtk.main() 

if __name__ == '__main__': 
    main() 
+0

go_mulit()은 마우스 포인터가 eventbox에서 멀어 질 때마다 호출됩니다! – Froyo

+0

예 답변을 게시 한 후에 보았습니다. 나는 대답을 편집 할 것이다. – savruk

관련 문제