python - Tkinter - 撤回前一个窗口而不是破坏它导致当前窗口出现问题
问题描述
我有一个使用登录窗口初始化的应用程序 - 一旦验证了用户和密码,它就会打开主菜单窗口(该窗口的代码如下)。以前,如果用户没有选择从主菜单注销以返回登录。但现在我插入了一个注销按钮,它应该杀死当前窗口打开以前的登录窗口。
问题是以前我不必保留登录窗口的状态,因为我从未计划返回那里,但现在我确实希望选择返回那里 - 所以我需要保留状态 - 因此我需要与之root.withdraw()
相反的用途root.destroy()
似乎是我问题的根源(没有双关语)
如果我直接在我的 IDE 上执行该main_menu_window()
函数 - 它可以 100% 工作,但如果我在下面的代码中从 LoginWindow(“父级”)调用它,我会收到如下详细信息的错误:
def main_menu_window(_parent, _user):
def open_user_man(event=None):
user_man_window(main_win)
main_menu_window(_user)
def open_prof_man(event=None):
prof_man_window(main_win, _user)
main_menu_window(_user)
def open_mon_leagues(event=None):
mon_leagues_window(main_win)
main_menu_window(_user)
def back_to_login():
main_win.destroy()
# if _parent is not None:
# _parent.deiconify()
# Hide Login Window
if _parent is not None:
_parent.withdraw()
# Window Setup
main_win = tk.Tk()
main_win.title("11Sixteen Database Management Controller - Main menu")
main_win.geometry("%dx%d+0+0" % (main_win.winfo_screenwidth(), main_win.winfo_screenheight()))
# Object setup
user_man = ImagedButtonWithText(main_win,
'C:\\Users\\rferreira\\GitHub\\11Sixteen\\DatabaseManagentController\\GlobalResources\\Images_Icons\\user_man_icon.png',
"LargeGroove", "User Management")
prof_man = ImagedButtonWithText(main_win,
'C:\\Users\\rferreira\\GitHub\\11Sixteen\\DatabaseManagentController\\GlobalResources\\Images_Icons\\profile_man_icon.png',
"LargeGroove", "Profile Management")
mon_leas = ImagedButtonWithText(main_win,
'C:\\Users\\rferreira\\GitHub\\11Sixteen\\DatabaseManagentController\\GlobalResources\\Images_Icons\\monitor_leagues_icon.png',
"LargeGroove", "Monitored Leagues")
back_to_mm_btn = ColourSchemedButton(main_win, "PaleGreen", "Logout", width=18)
# Object binding
user_man.btn.config(command=open_user_man)
prof_man.btn.config(command=open_prof_man)
mon_leas.btn.config(command=open_mon_leagues)
back_to_mm_btn.config(command=back_to_login)
# Object placement
back_to_mm_btn.grid(row=0, column=0, columnspan=2, padx=30, pady=20, sticky="nw")
user_man.frame.grid(row=1, column=0, padx=30, pady=20)
prof_man.frame.grid(row=1, column=1, padx=30, pady=20)
mon_leas.frame.grid(row=1, column=2, padx=30, pady=20)
main_win.mainloop()
if __name__ == "__main__":
user = User()
main_menu_window(None, user)
我得到的错误如下:
C:\Users\rferreira\AppData\Local\Programs\Python\Python39\python.exe C:/Users/rferreira/GitHub/11Sixteen/DatabaseManagentController/Login/LoginWindow.py
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\rferreira\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\rferreira\GitHub\11Sixteen\DatabaseManagentController\Login\LoginWindow.py", line 19, in login_process
validate_login(login_win, email_entry, password_entry, message_label)
File "C:\Users\rferreira\GitHub\11Sixteen\DatabaseManagentController\Login\LoginValidation.py", line 54, in validate_login
login_attempt()
File "C:\Users\rferreira\GitHub\11Sixteen\DatabaseManagentController\Login\LoginValidation.py", line 42, in login_attempt
MwW.main_menu_window(parent, user)
File "C:\Users\rferreira\GitHub\11Sixteen\DatabaseManagentController\MainMenu\MainMenuWindow.py", line 41, in main_menu_window
user_man = ImagedButtonWithText(main_win,
File "C:\Users\rferreira\GitHub\11Sixteen\DatabaseManagentController\GlobalResources\GuiObjectsFactories.py", line 45, in __init__
self.btn = LargeGroove(self.frame, image=image)
File "C:\Users\rferreira\GitHub\11Sixteen\DatabaseManagentController\GlobalResources\GUIObjectsComponents.py", line 20, in __init__
super().__init__(master=parent, width=130, height=130, relief="groove", **kw)
File "C:\Users\rferreira\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2650, in __init__
Widget.__init__(self, master, 'button', cnf, kw)
File "C:\Users\rferreira\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2572, in __init__
self.tk.call(
_tkinter.TclError: image "pyimage4" doesn't exist
我很乐意提供有关如何杀死此错误的任何帮助或想法。如果您需要更多详细信息或进一步的代码提取,请告诉我。
为了获得更好的上下文,下面是对触发错误的对象的进一步代码提取
class ImagedButtonWithText(tk.Frame):
def __init__(self, parent, image_path, btn_type, text, **kw):
self.frame = tk.Frame(parent)
# Set up button
image = PhotoImageComp(image_path)
if btn_type == "MicroGroove":
self.btn = MicroGroove(self.frame, image=image)
if btn_type == "LargeGroove":
self.btn = LargeGroove(self.frame, image=image)
self.btn.image = image
self.btn.grid(row=0, column=0)
# Set up text
self.label = tk.Label(self.frame, text=text)
self.label.grid(row=1, column=0)
# --------------------- Buttons ---------------------------
class MicroGroove(tk.Button):
def __init__(self, parent, **kw):
super().__init__(master=parent, width=30, height=20, relief="groove", **kw)
class LargeGroove(tk.Button):
def __init__(self, parent, **kw):
super().__init__(master=parent, width=130, height=130, relief="groove", **kw)
解决方案
Tkinter 从不强迫你传递主参数。你通常这样做:
self.label = tk.Label(self.frame, text=text)
self.frame
是标签的主人。同样,您应该在创建PhotoImage
s 时传入 master 参数,如下所示:
image = PhotoImage(image_path, master=parent)
仅当您有超过 1 个Tk()
实例时才需要这样做,但我建议始终通过它。
如果你不把它传入,tkinter 会假设 master 是Tk()
你创建的第一个实例。这是一个问题,因为 的不同实例Tk()
(大多数情况下)不能相互交谈,因此PhotoImage
根据 . 的第二个实例实际上并不存在Tk()
。
推荐阅读
- python - TemplateDoesNotExist, Django 路径很好但无法打开文件
- ios - UICollectionView 给出“索引超出范围”错误
- c++ - 将两个数字转换为单词
- c# - c# 度假村列表
- go - Go net/http 请求正文始终为 nil
- java - java中的short和char自动拆箱
- swift - 带有大标题的导航栏上的动画segue错误
- css - Checkbox hack - 通过位置隐藏复选框是否有缺点:绝对?
- java - 引起:org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有可用的“javax.validation.Validator”类型的合格bean
- wagtail - 通过model_mommy创建Wagtail页面