我正在为学校做一个倒计时(如电视节目)项目,这涉及用户在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语句时出现错误。我试着谷歌搜索所有这些,但没有成功;这是一个非常小众的问题。
编辑(我混淆了自己):我知道有人已经回答了这个问题,而且效果很好 - 当关闭其中一个窗口时,两个窗口都会自动关闭 - 但是由于我对课程的了解很朦胧,我无法让它与我的倒计时程序一起工作,我使用了一个带有一个窗口的类(这是我设法让网格方法工作的唯一方法)。
原则是一样的,所以我错误地认为我可以解决它,但是关于运行涉及另一个类的类的事情让我感到难过。两个窗口的内容混乱(例如,一个窗口的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)
第一个窗口显示一个计时器(倒计时),第二个窗口显示一个框,您可以在其中输入anagram的解决方案和您的玩家编号。下面的按钮允许玩家提交'这两件事(我在按钮命令程序中使用了' self。(text_entry_information).get' thingy)。 我没有试图让这些窗口同时运行,因为我做错了,这会让问题混乱。
再一次,任何帮助将不胜感激!
答案 0 :(得分:3)
您不能超过1 mainloop()
。即使您使用线程也不会,因为它会导致问题。但是你可以拥有多个tk.Toplevel
窗口,它的工作方式相同。
下面是一个例子:
import tkinter as tk
class Demo1:
def __init__(self, master):
self.master = master
self.master.title('Happening at the same time')
self.newWindow = tk.Toplevel(self.master)
self.app = Demo2(self.newWindow)
class Demo2:
def __init__(self, master):
self.master = master
self.master.title("Simultaneous Window")
def main():
root = tk.Tk()
app = Demo1(root)
root.mainloop()
if __name__ == '__main__':
main()
如您所见,我只有一个mainloop()
答案 1 :(得分:1)
尝试更频繁地导入tkinter,因为它对命名空间更好。这个答案是为了解决你的编辑。
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()
下次请写一个新问题,以便有更多人可以参与。由于您的编辑是一个完全不同的问题。