これは私がここで質問した最も複雑な質問かもしれません。私は私の問題を再現することができると思う最もシンプルな私のコードを取得する時間を費やしました。何か助けを得るのがあまりに複雑でないことを願っています...destroy()キューからトップレベルのtkinterがサイレントに失敗する(競合状態?)
基本的に以下のコードでは、単一のボタンを持つtkinterアプリケーションが作成され、100msごとにキューをチェックして、別のスレッドと対話する必要があります後で。新しいウィンドウも作成され、後でエラーが発生するので非常に素早く破棄します。(これは重要かもしれません)
ボタンをクリックすると、メインスレッドに(スレッドを介して)潜在的に時間のかかるものが起こっていることを示すために使用されるウィンドウを作成すると、ウィンドウが破棄されるようにメインスレッドに通知します。
問題は、時間のかかるタスクが非常に短く、エラーもなくても、スレッドのプロセスが長い時間(たとえば秒)を要した場合、期待どおりに動作してもウィンドウが破壊されないということです。
"新しいウィンドウオブジェクトは作成されておらず、まだnew_window
に割り当てられていますか?それで、私がキューにdestroyメソッドを追加すると、実際には古い(以前に破棄された)メソッドをキューに追加します "。それは私がアプリケーションを初期化するときに私がウィンドウを作成し、破壊しなければ私がボタンをクリックするとエラーが発生する理由を説明するだろうが、なぜ私はエラーが発生しないのか説明していないdestroy()
以前、私はその理論と権利だ場合、私は本当に解決策があるかわからないので、任意のアイデアが
import tkinter as tk
import queue
import threading
import time
def button_pressed():
threading.Thread(target=do_something_on_a_thread).start()
def do_something_on_a_thread():
global new_window
app_queue.put(create_a_new_window)
time.sleep(1)
app_queue.put(new_window.destroy)
def create_a_new_window():
global new_window
new_window = tk.Toplevel()
tk.Label(new_window, text='Temporary Window').grid()
#Check queue and run any function that happens to be in the queue
def check_queue():
while not app_queue.empty():
queue_item = app_queue.get()
queue_item()
app.after(100, check_queue)
#Create tkinter app with queue that is checked regularly
app_queue = queue.Queue()
app = tk.Tk()
tk.Button(app, text='Press Me', command=button_pressed).grid()
create_a_new_window()
new_window.destroy()
app.after(100, check_queue)
tk.mainloop()
ところで、これはよく書かれた質問です。あなたのコードはうまく書かれていて、素晴らしいMCVEで書かれていれば... :) –