8

スクリプトの 1 つに小さな GUI を作成しました。すべてがうまくいっています。

1 つのボタンをクリックすると、いくつかの Web サイトから大量のデータを解析する大きな機能が起動します。

しかし、ボタンをクリックすると、関数が完全に実行されるまでプログラムがフリーズします。すべて正常に動作していますが、関数の実行中に GUI がフリーズするのはなぜですか。小さな進行状況バーを印刷したいのですが、それはできません。

以下はプログラムの一部です。

    self.Button1 = Button(self.MENU, text="IELTS", command=self.My_Command)
    self.Button1.grid(row=0, column=0,sticky=W+E)

def My_Command(self):

    ## HERE WE LAUNCH THE FUNCTION
    Module_1.main() # My Big Function from another file

    self.Button1.config(text="DONE")

Module_1.main() の実行中に何も実行/印刷できません ... GUI が完全にフリーズします。

Module_1.main() 関数はスレッド化されたパーサー (2 つの Web サイトからの一部のデータを解析する) であり、実行には通常 2 分かかります。この関数の実行に必要な 2 分間でプログラムとやり取りできるという考えを誰かが持っている場合、それは非常に役に立ちます。

4

1 に答える 1

6

Tkinterはシングルスレッドです。画面の更新は、イベントループを通過するたびに行われます。長時間実行されるコマンドがある場合は常に、イベントループが反復を完了するのを防ぎ、イベントの処理を防ぎ、再描画を防ぎます。

唯一の解決策は、a)長時間実行コマンドにスレッドを使用する、b)長時間実行コマンドにプロセスを使用する、またはc)コマンドを小さなチャンクに分割してそれぞれを数ミリ秒で実行できるようにすることです。イベントループの後続の反復中のチャンク。ウィジェットのメソッドを定期的に呼び出すというもう1つの解決策がありますが、これはupdate_idletasks修正というよりも回避策です。

Tkinterはスレッドセーフではないため、スレッドの使用には特別な注意が必要です。メインスレッドからのみウィジェットのメソッドを呼び出すことができます。つまり、他のスレッドはスレッドセーフキューを介してメインスレッドと通信する必要があります。

于 2012-06-01T10:55:38.043 に答える