1

ディスク上のファイルをコピーし、その進行状況を Tkinter GUI に表示するアプリを開発しました。ファイルをコピーするためのカスタマイズされた shutil モジュールを使用します。カスタマイズしたコピー機能を (GUI を使用せずに) 直接使用してファイルをコピーすると、すべてのファイルが適切にコピーされ、コピー中のファイルに関するメッセージが表示されます (コピー中に print ステートメントを使用しました)。問題は、GUI を使用して同じ操作を実行すると、しばらくするとハングすることです。

テキストウィジェットを使用して、コピー中のファイルの実行ログを表示しています。基本的に、コピー関数を呼び出す前に stdout をリダイレクトし、「update_idletasks」を使用して GUI を更新しています。

class TextRedirector(object):
    def __init__(self, widget, tag="stdout"):
        self.widget = widget
        self.tag = tag

    def write(self, str):
         self.widget.configure(state="normal")
         self.widget.insert("end", str, (self.tag,))
         self.widget.update_idletasks()
         self.widget.see('end')
         self.widget.configure(state="disabled")

クエリ 1: テキスト ウィジェットのテキスト サイズに制限はありますか? このハングの問題に対処するには、コードで何を調べればよいでしょうか。

クエリ 2 : コピー機能が呼び出されると、「最小化」ボタンを使用できないことに気付きました。この操作が終了すると、使用できるようになります。私の場合、大量のデータをコピーする必要があるため、アプリを最小化して他の作業を続行したいと考えています。

更新:(作業ソリューション)

updateの代わりにメソッドを使用すると、両方のクエリが解決されますupdate_idletasks。なぜそれがうまくいかなかったのか、私の質問update_idletasksです。私の知る限りでは、GUI イベントを更新するためにも使用されます。

class TextRedirector(object):
    def __init__(self, widget, tag="stdout"):
        self.widget = widget
        self.tag = tag

def write(self, str):
     self.widget.configure(state="normal")
     self.widget.insert("end", str, (self.tag,))
     self.widget.update()
     self.widget.see('end')
     self.widget.configure(state="disabled")
4

1 に答える 1

1

テキスト ウィジェットには実質的なサイズ制限はありません。

実際にどのようにデータをコピーしているかを確認しないと、確実に知ることはできませんが、Tkinter がシングル スレッドであることはご存知ですか? 時間がかかるコマンドがある場合、GUI はその操作が完了するまでハングします。これは、すべての GUI 操作がイベントに応答して発生し、個々のコマンドが実行されている間はイベント ループがイベントに応答できないためです。

回避策は、長時間実行される操作をスレッドまたは別のプロセスで実行することです。または、その関数をリファクタリングして、イベント ループの各反復で小さなチャンクの作業を実行できるようにすることもできます。スレッドを使用する場合、この別のスレッドから GUI ウィジェットに直接書き込むことはできないことに注意してください。スレッド間でデータを送信するには、スレッド セーフ キューを使用する必要があります。

于 2012-09-11T11:56:27.613 に答える