メインループを別のスレッドで実行しないでください。 AFAIKでは、メインループはウィジェットを作成したのと同じスレッドで実行する必要があります。
私が慣れ親しんだGUIツールキット(Tkinter、.NET Windows Forms)はそういったものです。GUIはあるスレッドからのみ操作できます。以下の
self.tk.mainloop(n)
RuntimeError: Calling Tcl from different appartment
一つは動作します(余分なスレッド):
if __name__ == '__main__':
t = tk.Tk()
t.iconbitmap('icon.ico')
b = tk.Button(text='test', command=exit)
b.grid(row=0)
t.mainloop()
余分な糸で:
def threadmain():
t = tk.Tk()
t.iconbitmap('icon.ico')
b = tk.Button(text='test', command=exit)
b.grid(row=0)
t.mainloop()
if __name__ == '__main__':
thread.start_new_thread(threadmain,())
while 1:
sleep(1)
Linuxの
は、あなたのコードは、例外を発生させます
コミュニケーションが必要な場合tkinterスレッドの外部からのtkinterで、作業のためにキューをチェックするタイマーを設定することをお勧めします。ここで
は一例です:
import Tkinter as tk
import thread
from time import sleep
import Queue
request_queue = Queue.Queue()
result_queue = Queue.Queue()
def submit_to_tkinter(callable, *args, **kwargs):
request_queue.put((callable, args, kwargs))
return result_queue.get()
t = None
def threadmain():
global t
def timertick():
try:
callable, args, kwargs = request_queue.get_nowait()
except Queue.Empty:
pass
else:
print "something in queue"
retval = callable(*args, **kwargs)
result_queue.put(retval)
t.after(500, timertick)
t = tk.Tk()
t.configure(width=640, height=480)
b = tk.Button(text='test', name='button', command=exit)
b.place(x=0, y=0)
timertick()
t.mainloop()
def foo():
t.title("Hello world")
def bar(button_text):
t.children["button"].configure(text=button_text)
def get_button_text():
return t.children["button"]["text"]
if __name__ == '__main__':
thread.start_new_thread(threadmain,())
trigger = 0
while 1:
trigger += 1
if trigger == 3:
submit_to_tkinter(foo)
if trigger == 5:
submit_to_tkinter(bar, "changed")
if trigger == 7:
print submit_to_tkinter(get_button_text)
sleep(1)
さてあなたは、それが動作...頭の上に釘を打ってきましたが、私は十分な情報を提供していないに苦しんできました。 私の推論は、whileループがどこにあるのかをtkinterに任せたいと思っています... 私はあなたの答えを受け入れて、別の、もっと冗長な質問をするべきですか? – burito
こんにちは、私はこれを達成するための提案とコードの例で私の答えを更新しました。 whileループは、要求/応答キューを使用して、tkinterスレッド上でいくつかのメソッドを呼び出します。 – codeape
ところで、プロダクションコードでは、Tkinterウィンドウ、スレッド、およびキューをクラスにカプセル化することをお勧めします。これは、現在のグローバルを避けるためです:request_queue、response_queue、およびt。また、callable(* args、** kwargs)に関するいくつかのエラー処理が必要です。 – codeape