在我的Tkinter应用程序中,我有一个按钮,可以打开一个Toplevel窗口来显示事件日志。我需要Toplevel Window能够做的一些事情:
我已经找到了#1。我可以打开窗口并显示以前的条目,并在窗口打开时更新这些条目。我的问题是#2和#3。
对于#2我不知道如何禁用用户移动窗口的能力。我假设这也可能会禁用用户关闭窗口的能力,因此我不确定如何保持该功能完好无损。也许是一个按self.quit()
的按钮?
至于#3,我不知道如何去做。也许我像谷歌搜索一样,但我似乎无法找到如何实现这一点。
这是我目前的代码,它能够正确实现功能#1。
import tkinter as tk
class guiapp(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
self.value = 0.0
self.alive = True
self.list_for_toplevel = []
btn = tk.Button(self.master, text = "Click", command = self.TextWindow)
btn.pack()
def TextWindow(self):
self.textWindow = tk.Toplevel(self.master)
self.textFrame = tk.Frame(self.textWindow)
self.textFrame.pack()
self.textArea = tk.Text(self.textWindow, height = 10, width = 30)
self.textArea.pack(side = "left", fill = "y")
bar = tk.Scrollbar(self.textWindow)
bar.pack(side = "right", fill = "y")
bar.config(command = self.textArea.yview)
self.alive = True
self.timed_loop()
def timed_loop(self):
if self.alive == True and tk.Toplevel.winfo_exists(self.textWindow):
self.master.after(1000, self.timed_loop)
self.value += 1
self.list_for_toplevel.append(self.value)
self.textArea.delete(1.0, "end-1c")
for item in self.list_for_toplevel:
self.textArea.insert('end', "{}\n".format(item))
self.textArea.see('end')
else:
self.alive = False
if __name__ == "__main__":
root = tk.Tk()
root.geometry("800x480")
myapp = guiapp(root)
root.mainloop()
答案 0 :(得分:1)
我们可以从toplevel
窗口的顶部删除工具栏,并阻止用户使用self.textWindow.overrideredirect(True)
移动窗口。
然后,我们可以通过获取根窗口位置确保toplevel
窗口位于右上角,然后将toplevel
窗口设置为self.master.winfo_x()
的同一位置, self.master.winfo_y()
。
最后我会添加一个关闭窗口的按钮,因为我们不再拥有toplevel
窗口的工具栏。
更新:我添加了toplevel
窗口保持在根窗口顶部的功能,并在拖动root时使用根窗口移动。
我们可以使用bind()
来跟踪移动根窗口的时间,然后使用一个函数来更新toplevel
窗口位置以匹配根窗口。
我们还可以使用self.textWindow.attributes("-topmost", True)
告诉tkinter在所有其他窗口之上保留toplevel
窗口。
请查看下面代码的修改版本。让我知道您的想法或者您是否有任何问题。
import tkinter as tk
class guiapp(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
self.textWindow = None
self.master.bind("<Configure>", self.move_me)
self.value = 0.0
self.list_for_toplevel = []
btn = tk.Button(self.master, text = "Click", command = self.TextWindow)
btn.pack()
def TextWindow(self):
x = self.master.winfo_x()
y = self.master.winfo_y()
self.textWindow = tk.Toplevel(self.master)
self.textFrame = tk.Frame(self.textWindow)
self.textWindow.overrideredirect(True)
self.textFrame.pack()
self.textWindow.attributes("-topmost", True)
self.textWindow.geometry('+{}+{}'.format(x+10, y+30))
self.close_toplevel = tk.Button(self.textWindow, text = "close", command = self.close_textWindow)
self.close_toplevel.pack()
self.textArea = tk.Text(self.textWindow, height = 10, width = 30)
self.textArea.pack(side = "left", fill = "y")
bar = tk.Scrollbar(self.textWindow)
bar.pack(side = "right", fill = "y")
bar.config(command = self.textArea.yview)
self.alive = True
self.timed_loop()
def close_textWindow(self):
self.textWindow.destroy()
self.textWindow = None
def move_me(self, event):
if self.textWindow != None:
x = self.master.winfo_x()
y = self.master.winfo_y()
self.textWindow.geometry('+{}+{}'.format(x+10, y+30))
def timed_loop(self):
if self.textWindow != None:
self.master.after(1000, self.timed_loop)
self.value += 1
self.list_for_toplevel.append(self.value)
self.textArea.delete(1.0, "end-1c")
for item in self.list_for_toplevel:
self.textArea.insert('end', "{}\n".format(item))
self.textArea.see('end')
if __name__ == "__main__":
root = tk.Tk()
root.geometry("800x480")
myapp = guiapp(root)
root.mainloop()