pygtkでスレッドを操作する方法
-
03-07-2019 - |
質問
pygtkのスレッドに問題があります。私のアプリケーションは、インターネットから画像をダウンロードし、pygtkで表示するプログラムで構成されています。問題は、これを実行してGUIの応答性を維持するために、スレッドを使用する必要があることです。
ユーザーが[画像のダウンロード]ボタンをクリックした後、コールバックになりました。そして、同じクラス内にある写真をダウンロードするメソッドを呼び出します。
thread.start_new_thread(self.images_download、(path、pages)
これは機能しません。プログラムをスレッドに入れる唯一の方法は、
gtk.threads_init()
スレッドを開始する前。これで、写真がダウンロードされますが、GUIは応答しません。 私はこれをグーグルで調べ、gtk.threads_enterとgtk.threads_leaveをスレッドの周りに配置しようとしましたが、うまくいきません。
解決
あなたの質問は少し曖昧で、実際のコードへの参照がなければ、あなたが間違っていることを推測するのは難しいです。
だから、読むための指針をいくつか挙げて、経験に基づいて乱暴に推測します。
まず第一に、スレッドを使用することによってのみGUIの応答性を維持できると考えているようです。本当じゃない。コードを非同期で記述し、すべてをシングルスレッドアプリケーションで実行することもできます。 Twisted は、このプログラミングモデルに基づいています。最近ブログ投稿を作成して、非同期タスクインターフェースの作成方法と例を説明しますCLIとGTK +の両方のランナー。これらの例を見て、タスクを非同期に実装する方法を確認してください。UIは引き続き更新されます。
第二に、何らかの理由でスレッドを使用する場合は、GTK +スレッドモデルを少し理解する必要があります。
このテーマに関するPyGTK FAQエントリを読むことから始めます。 、このブログ投稿わかりやすい。
今、推測に移ります。私はあなたがスレッドからGTK UIを更新しようとしており、ロックを適切に処理していないと推測しています。この場合、gobject.idle_add()を使用して、スレッドからメインスレッドに実行するすべてのUI更新を延期するほうがよいでしょう。この方法では、すべてのUI呼び出しがメインスレッドから行われます。プログラミングで従うのが簡単なメンタルモデルです。
スレッドモデルとロックモデルを本当に理解したら、スレッドからUIを更新することを検討できますが、threads_enter()/ threads_leave()を見逃すのは簡単です
他のヒント
gtk.gdk.threads_enter()およびgtk.gdk.theads_leave()ロックを使用してUIを変更するスレッドを許可するには、gtk.gdk.threads_init()を使用できますが、これに関する問題はWindowsではうまく機能しません。 Linuxでテストし、非常に優れたパフォーマンスを発揮しましたが、これをwin32で動作させることはできませんでした。
===編集===
私はこれについてブラウジングしてきましたが、gobject.io_add_watchを使用してソケットに何かがあるかどうかを確認し、それをつかんでGUIを更新できます。これについての私の投稿を確認してください: ソケット(および他のいくつかのファイル)とスレッドのないPyGTK。