1

Tkinter GUI でボタンを押して外部関数を呼び出そうとしています。関数 'insert' を Text 要素に挿入します。これは完全に機能します。time.sleep() がすぐ後に続かない限り。従わない場合、テキストは正しく更新されます。そうである場合、テキストは更新されませんが、関数はまだループを実行しているように見えますが、コンソールにテキストを喜んで出力します。

これが私のスクリプト例です:

from Tkinter import *
from time import sleep

def test_function(gui_self):
    while True:
        print "Debug message"
        gui_self.main_.insert(END, "Test")


class GUI:
    def __init__(self, master):
        frame = Frame(master, width=300, height=500)
        frame.pack()
        self.main_ = Entry(frame, width=80, justify=CENTER)
        self.main_.pack()

        test_function(self)

root = Tk()
application = GUI(root)
root.mainloop()

これはうまくいきます。ただし、test_function を次のように変更すると、問題が発生するようです。

def test_function(gui_self):
    while True:
        print "Debug message"
        gui_self.main_.insert(END, "Test")
        sleep(5)

ここで間違っていることを修正するための提案はありますか? 私は、かなり基本的なレベルのユーザーとして、正しい構文を使用していないだけの問題だと確信しています。

補足として、「sleep」コマンドもプログラムを完全にフリーズしているように見えますが、これはかなり面倒で魅力的ではありません。スレッドを「パイプ」する以外に、可変的に設定された時間 (var = 1(秒) など) ループを一時停止する方法はありますか?

ありがとう。

4

2 に答える 2

3

一般に、シングルスレッド GUI を呼び出さないtime.sleepでください。そうしないと、発見したようにブロックされます。

スリープを処理する正しい方法は、GUI イベントを使用することです。

すべての TK ルート ウィンドウにある方法を使用する方法を示す別のスタック オーバーフローの質問で、この例を参照してください。after

于 2012-05-12T13:56:58.553 に答える
3

Nick Craig-Woodの答えに完全に同意します-GUIのメインスレッドをスリープ状態にしないでください。一般に、after(およそ) X ミリ秒後に呼び出される関数を登録する呼び出しを行います。test_function5 秒ごとに呼び出す例を次に示します。test_function が呼び出されるたびに、5 秒後に呼び出されるように再登録されます。

def test_function(gui_self):
    print "Debug message"
    gui_self.main_.insert(END, "Test")
    gui_self.after(5000,test_function,gui_self)
    #the line below also should work.  As long as the item is a Tkinter widget
    #gui_self.main_.after(5000,test_function,gui_self) 

また、まったく関係ありませんが (ただし、スタイルの問題として) 、単に の代わりにmain_in を使用している理由はありますか? 一般に、python キーワードを使用した名前衝突の回避には、末尾のアンダースコアが追加されます。私の知る限り、キーワードではありません。GUImainmain

于 2012-05-12T14:37:37.963 に答える