スレッドはGUIイベントでのみ機能します - pygtk

スレッドはGUIイベントでのみ機能します - pygtk

私はpygtkでマルチスレッドアプリケーションを開発していますが、quicklyを使用してスレッドに固執しています。そこで、さまざまな可能性を試してみたところ、GUIで何かを行うときだけスレッドが機能することがわかりました。これが私のコードです。

t = threading.Thread(target=self.calc,args=(treeiter))
t.daemon = True
t.start()

    def calc(self,treeiter):
        store=self.builder.get_object('liststore1')
        per=0
        while 1:
            print "Calcing and changing percent,per="+str(per)
            tore.set_value(treeiter,4,str(int(per))+"%")
            per+=1
            time.sleep(1)

スレッドで値を更新しようとしていますliststoreが、ボタンやその他の GUI イベントをクリックしたときにのみ更新されます。なぜでしょうか。スレッドがバックグラウンドで実行されていないのはなぜでしょうか。

答え1

スレッドと GTK は必ずしもうまく連携するとは限りません。役に立つトリックはいくつかありますが、奇妙なバグが発生しても驚かないでください。最近、アプリケーションからすべてのスレッドを削除したところ、はるかに使いやすくなりました。

したがって、最初に考えるべきことは、GLib の非同期メソッドを活用するようにアプリケーションを書き直すことができるかどうかです。

スレッドをどうしても使用したい場合は、次の 2 つのルールに留意してください。

  1. コードのできるだけ早い段階でGLib.treads_init()を呼び出します。
  2. スレッド内でGUIイベントを呼び出す場合は、GLib.idle_add()でラップします。

これらはルールであり、ガイドラインではありません。いつもスレッドを操作するときにこれを実行してください。

答え2

gtk を使用している場合、time.sleep() を使用するのは得策ではありません。タイマー イベントの使用を試みることができます。(私は quickly をもう使用していませんが、これでうまくいくと思います。)

from gi.repository import GLib

class Just_for_correct_coding():
    self.per = int()

    def start(self):
        GLib.timeout_add_seconds(1, self.calc)

    def calc(self,treeiter):
        store=self.builder.get_object('liststore1')
        print "Calcing and changing percent,per="+str(self.per)
        tore.set_value(treeiter,4,str(int(self.per))+"%")
        self.per+=1
        return True #important if you want to keep the timer running

関連情報