咨询Tkinter中self.transient(master)实现对话框关联注册窗口的使用位置
如何正确使用
self.transient(master)让注册窗口始终显示在主窗口上方 嘿,我来帮你搞定这个问题!首先先理清transient()方法的作用:它能把一个Toplevel窗口标记为另一个窗口的"临时从属窗口",这样这个从属窗口会始终悬浮在主窗口之上,而且当主窗口关闭时,它也会自动关闭,非常适合做对话框类的窗口。
你的代码里的两个关键问题:
- 多余的Toplevel创建:你已经让
registration_window继承了Toplevel,但在reg_window方法里却先创建了一个新的Toplevel,再把它传给registration_window的构造函数——这等于创建了两层Toplevel窗口,不仅冗余,还会导致transient无法正确关联到主窗口。 self.transient的调用逻辑问题:即使你取消注释那行代码,因为上面的错误,它也无法作用到真正的主窗口上。
修正后的正确做法:
步骤1:调整reg_window方法,直接关联主窗口
把原来的代码:
def reg_window(self): self.newWindow = tk.Toplevel(self.master) self.app = registration_window(self.newWindow)
改成:
def reg_window(self): self.app = registration_window(self.master)
这样registration_window的master参数就直接关联到主窗口(menu类里的root),不再需要多余的中间Toplevel。
步骤2:正确放置self.transient(master)
在registration_window的__init__方法里,初始化完self.master之后,任何位置调用都可以,通常放在窗口属性配置(title、geometry等)的前后都没问题。另外别忘了调用父类的构造函数,确保窗口初始化正确:
class registration_window(Toplevel): def __init__(self, master): super().__init__(master) # 必须调用父类Toplevel的构造函数 self.master = master self.transient(master) # 在这里设置为临时从属窗口,关联主窗口 self.title('Registration Form') self.geometry('1230x650') self.configure(background="#98ff98") self.iconbitmap("e:\\library\\image\\save.ico") # 后续控件代码...
额外修复:entry_set函数的小bug
你原来的entry_set函数直接用了item_entry变量,但这个变量是registration_window里的局部变量,应该改成用传入的entry参数:
def entry_set(entry, text): entry.delete(0, 'end') entry.insert(END, text)
最终修正后的完整代码
from tkinter import * import tkinter as tk from tkinter import ttk from tkinter.filedialog import askopenfilename class menu(): def __init__(self, master): self.master = master master.title('Library Management Software') master.geometry('1230x650') master.configure(background="#98ff98") master.iconbitmap("e:\\library\\image\\save.ico")#添加标题栏图标 menubar = Menu(master) membermenu = Menu(menubar, tearoff=0) membermenu.add_command(label = "Member" , command = self.reg_window) menubar.add_cascade(label = "Entry", menu = membermenu) master.config(menu = menubar) def reg_window(self): # 直接创建registration_window实例,传入主窗口作为master self.app = registration_window(self.master) class registration_window(Toplevel): def __init__(self, master): super().__init__(master) # 初始化父类Toplevel self.master = master self.transient(master) # 设置为主窗口的临时从属窗口 self.title('Registration Form') self.geometry('1230x650') self.configure(background="#98ff98") self.iconbitmap("e:\\library\\image\\save.ico")#添加标题栏图标 item_file = StringVar() image_label = Label(self, text="Photo: ", bg="gray74", relief="groove") image_label.place(x=755,y=150) item_entry = Entry(self, textvariable=item_file,width=35) item_entry.place(x=795,y=150) self.item_button = Button(self, text="\uD83D\uDCC2", relief="groove", command=lambda:entry_set(item_entry, askopenfilename())) self.item_button.place(x=1000, y=150, height=20, width=20) def entry_set(entry, text): entry.delete(0, 'end') entry.insert(END, text) def main(): root = tk.Tk() app = menu(root) root.mainloop() if __name__ == '__main__': main()
这样修改后,你的注册窗口就会始终显示在主窗口之上,完美实现你想要的效果啦!
内容的提问来源于stack exchange,提问作者Soumen Saha
相关产品推荐
相关产品推荐

