2012-02-14 12 views
1

私はつぶやきを得るためのGUIを作っています。私は信号を受け取り、テキストビューを変更するイベントボックスを作った。 マルチ処理を使用してテキストビューを変更していますが、変更されません。私は窓の大きさを変えようと試みました。しかし何も変わりません。私はtextviewのtextbufferを得ることができますが、それを変更することはできません。別のプロセスからテキストビューを変更するにはどうすればよいですか?

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がフリーズすることがあります。だから、私はそれがプロセスを作り、タイムラインを取得してtweetbufferを設定するようにしたかったのです。しかし、私はtweetbufferにテキストを設定することができません。

答えて

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使用してウィジェットを更新します(時々、彼らは同じじゃないなぜかGObject.idle_addを、私は完全には理解しません)
  2. [here]を説明しているものに従います。それは基本的に言う:あなたはGtk.main()を呼び出す前に

    • は、以下のメソッドを呼び出します。あなたのスレッドで

      GObject.threads_init() 
      Gdk.threads_init() 
      
    • を、とのGtkウィジェットを更新するコード囲む:

      Gdk.threads_enter() 
      # your code here 
      Gdk.threads_leave() 
      
+0

ありがとう!それは私をたくさん助けています。私はかつてマルチスレッドを試みましたが、うまく動作しませんでした。だから、私はmutliprocessingを試みました。 は今、私は – Froyo

+0

@Froyoをマルチスレッド化のためのつもりです:これはあなたがおよび/または私の答えを、投票まで受け入れるつもりだという意味でしょうか? :D –

+0

どうもありがとう!今はうまくいっています! – Froyo

2

何かが表示される前に、メインループを実行してレンダリングイベントを処理する必要があります。

また、GTK関数を2番目のスレッドから呼び出さないでください。

あなたが始めるためにこれを読む: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は()マウスポインタがイベントボックスから離れるたびに呼び出され! – Froyo

+0

私は答えを投稿した後、はい、私はそれを見ました。私は答えを編集する – savruk

関連する問題