一般に、Tkinter アプリケーション内に無限ループを配置することはできません。なんで?すでに無限ループ、つまりイベント ループを実行しています。あなたのコードはこれと同等です:
while <there are more events to service>:
while True:
<run code in here>
<get the next event>
<service the event>
問題が見えますか?コードがイベントにサービスを提供するのを妨げており、イベントは GUI の生命線です。
代わりに、ループ内で実行するコードを追加して、すでに実行中の無限ループを利用する必要があります。これはafter
(およびafter_idle
) で行います。これにより、1 つがキューに入れられます。そのイベントの処理中に を再度呼び出しafter_idle
た場合、イベント ループ内で機能する無限ループが効果的に設定されています。
例えば:
def do_one_iteration(self):
<run code in here>
self.after(100, self.do_one_iteration)
次に、メイン ロジックのどこかで、またはボタンに応答して、 を呼び出しますdo_one_iteration
。以前の無限ループを 1 回繰り返します。それが完了すると、Tkinter に 100 ミリ秒後に自分自身を再度呼び出すように指示します。その期間が経過すると、コードが実行され、100 ミリ秒などで別の反復がスケジュールされます。間隔は必要に応じて変更できます。間隔が短いほど、コードの実行は速くなりますが、イベントのために GUI が不足する可能性が高くなります。
<run code in here>
これは、比較的高速に実行する場合にのみ機能することに注意してください。実行中に GUI がフリーズします。数百ミリ秒で 1 回の反復を完了できるかどうかは、ユーザーにはわかりません。1秒以上かかると目立ちます。
注: この例では、メイン アプリケーションが Tkinter ウィジェットから継承するオブジェクトであると想定しています。そうでない場合でも機能する場合は、self
パラメーターを削除するだけです。さらに優れた解決策は、オブジェクトを使用するように GUI をリファクタリングすることです。これは、GUI を実装するはるかに柔軟な方法です。