私は学校向けの (テレビ番組のような) カウントダウン プロジェクトを行っています。これには、ユーザーが (時間的制約の下で) tkinter Text() エントリに応答を入力する短い期間が含まれます。このサイトの以前の回答のおかげで、画面上の tkinter タイマーを作成する方法を知っていて、非常に基本的なスレッド デバイスを使用して、ユーザーの Text() 入力ウィンドウと同時にそれを設定しました。
ユーザーが Text() 入力ウィンドウを早く閉じたときに時計を閉じることを気にしなければうまくいきますが、ユーザーがそれを完了した後も刻み続けるのはばかげているように感じます。そこで、ユーザーが入力ウィンドウを閉じて早期に回答を送信できるようにするコード (「WM_DELETE_WINDOW」など) も挿入しました。これにより、同時にタイマーが閉じます。この時点の後、これによりプログラムがフリーズし、修正方法がわかりません。これは、私が使用したコードの簡略化されたバージョンです (問題はまったく同じです)。
import threading
from tkinter import *
def backgroundWindow():
global root
root = Tk()
root.title("Happening at the same time")
root.mainloop()
threadWindow = threading.Thread(target=backgroundWindow)
threadWindow.start()
print() # The threading did NOT work without this print statement (?)
def destroyer():
global root
newRoot.destroy()
root.destroy()
newRoot = Tk()
newRoot.title("Simultaneous Window")
newRoot.protocol("WM_DELETE_WINDOW", destroyer)
newRoot.mainloop()
# program freezes up here (but does not finish)
print("Now the program continues") # does NOT get printed
また、中央にランダムに見えるprintステートメントがないと2番目のウィンドウが表示されなかった理由についても混乱しています。これらすべてをグーグルで調べてみましたが、成功しませんでした。これはかなりニッチな問題です。
編集(私は自分自身を混乱させました):
誰かがすでにこの質問に答えていることは知っていますが、うまく機能します-ウィンドウのいずれかを閉じると、両方のウィンドウが自動的に閉じます-しかし、クラスに関する知識がぼんやりしているため、カウントダウンプログラムで機能させることができませんでした。クラスのいずれかのウィンドウ (グリッド メソッドを機能させることができた唯一の方法でした)。
原理はまったく同じなので、自分で理解できると勘違いしていましたが、別のクラスを巻き込んだクラスの運営に戸惑いました。2 つのウィンドウの内容がごちゃごちゃになり (たとえば、一方のウィンドウの bg 色が意図せずに他方のウィンドウに適用されていた)、一方のウィンドウを閉じると、もう一方のウィンドウは開いたままになっていました。クラスと非クラスをクラスとともに実行するためのヒントを持っている人はいますか? スレッド化されていないコードは次のとおりです。
def conundrumClock():
global threading, playerAnswer, playerNumber, tkinter
def clock():
global threading, rootA
def countdown(time): # (I copied this from a previous answer by Bryan Oakley)
global threading
if time == -1:
rootA.destroy()
else:
if time == 0:
label.configure(text="TIME UP!")
else:
label.configure(text="Time remaining: %d seconds" % time)
rootA.after(1000, countdown, time-1)
rootA = Tk()
rootA.title("COUNTDOWN CLOCK")
label = Label(rootA, width=30)
label.pack(padx=20, pady=20)
countdown(15)
rootA.mainloop() # I am aiming to get rid of this
class AnswerEntry(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.anagram = Label(self, text="Your anagram solution", bg="light cyan", font=(None, 15), width=18, height=2, anchor=E)
self.numerics = Label(self, text="Player number (1 or 2)", bg="light cyan", font=(None, 14), width=19, height=2, padx=4, anchor=E)
self.anagram.grid(row=1, sticky=E, pady=1)
self.numerics.grid(row=2, padx=(7,0), pady=5)
self.solution = tk.Text(self, height=2, width=17,font=(None,15))
self.number = tk.Text(self, height=2, width=17, font=(None, 15))
self.solution.grid(row=1, column=1)
self.number.grid(row=2, column=1)
self.button1 = tk.Button(self, text=" SUBMIT YOUR NAME ", bg="cyan", fg="black", width=20, height=1, font=(None, 11), anchor=W, command=self.answer)
self.button2 = tk.Button(self, text="SUBMIT PLAYER NUMBER ", bg="cyan", fg="black", font=(None, 11), padx=3, command=self.the_number)
self.button1.grid(row=100, column=1, sticky=E)
self.button2.grid(row=100, column=0, sticky=W)
def answer(self):
global playerAnswer
playerAnswer = self.solution.get('1.0', END)
def the_number(self):
global playerNumber
playerNumber = self.number.get('1.0', END)
root = AnswerEntry()
root.title("REMEMBER TO PRESS THE BUTTONS!")
root.geometry("500x150")
root["bg"] = "aquamarine"
center(root) # (this is a function I got to center the window from a previous answer)
最初のウィンドウにはタイマー (カウント ダウン) が表示され、2 番目のウィンドウにはアナグラムへのソリューションとプレーヤー番号を入力するボックスが表示されます。下にあるボタンを使用すると、プレーヤーはこれらの両方を「送信」できます (ボタン コマンド プロシージャで「self.(text_entry_information).get」を使用しました)。これらのウィンドウを同時に実行する試みは省略しました。やり方を間違えると、質問が混乱するからです。
繰り返しになりますが、どんな助けでも大歓迎です!
名前空間に適しているため、tkinter のみを tk としてインポートする頻度を増やしてください。この回答は、EDITに対処するためのものです。
import tkinter as tk
def clock(root):
global rootA
def countdown(time):
if time == -1:
destroyer() #invokes the destroy function
else:
if time == 0:
label.configure(text="TIME UP!")
else:
label.configure(text="Time remaining: %d seconds" % time)
rootA.after(1000, countdown, time-1)
rootA = tk.Toplevel(root) #Made it a tk.Toplevel instead of a new root
rootA.protocol("WM_DELETE_WINDOW", destroyer) #set the window close protocol
rootA.title("COUNTDOWN CLOCK")
label = tk.Label(rootA, width=30)
label.pack(padx=20, pady=20)
countdown(15)
class AnswerEntry(tk.Tk):
def __init__(self):
super().__init__() #I changed tk.Tk.__init__(self) to this
self.title("REMEMBER TO PRESS THE BUTTONS!") #I placed them here since they are the same thing
self.geometry("500x150")
self["bg"] = "aquamarine"
self.protocol("WM_DELETE_WINDOW", destroyer)
self.anagram = tk.Label(self, text="Your anagram solution", bg="light cyan", font=(None, 15), width=18, height=2, anchor=tk.E)
self.numerics = tk.Label(self, text="Player number (1 or 2)", bg="light cyan", font=(None, 14), width=19, height=2, padx=4, anchor=tk.E)
self.anagram.grid(row=1, sticky=tk.E, pady=1)#Changed all your 'W' and 'E'... to 'tk.W' and 'tk.E'
self.numerics.grid(row=2, padx=(7,0), pady=5)
self.solution = tk.Text(self, height=2, width=17,font=(None,15))
self.number = tk.Text(self, height=2, width=17, font=(None, 15))
self.solution.grid(row=1, column=1)
self.number.grid(row=2, column=1)
self.button1 = tk.Button(self, text=" SUBMIT YOUR NAME ", bg="cyan", fg="black", width=20, height=1, font=(None, 11), anchor=tk.W, command=self.answer)
self.button2 = tk.Button(self, text="SUBMIT PLAYER NUMBER ", bg="cyan", fg="black", font=(None, 11), padx=3, command=self.the_number)
self.button1.grid(row=100, column=1, sticky=tk.E)
self.button2.grid(row=100, column=0, sticky=tk.W)
def answer(self):
global playerAnswer
playerAnswer = self.solution.get('1.0', tk.END)
def the_number(self):
global playerNumber
playerNumber = self.number.get('1.0', tk.END)
def destroyer():
rootA.destroy() #When the window closes
root.destroy()
if __name__ == '__main__':
root = AnswerEntry()
clock(root)
root.mainloop()
次回は新しい質問を書いて、より多くの人が質問できるようにしてください。あなたの EDIT はまったく別の質問だったので。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加