【问题标题】:Problem Loading The Tkinter window for second time第二次加载 Tkinter 窗口时出现问题
【发布时间】:2019-02-25 15:17:24
【问题描述】:

所以我正在尝试为我开发的 Tkinter 应用程序制作主菜单,但是当我单击按钮上的一个以打开另一个文件(即另一个窗口)时出现问题,但是当我关闭该窗口时并尝试通过单击主菜单中的相同按钮再次打开它,我收到此错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "c:\users\alireza\anaconda3\Lib\tkinter\__init__.py", line 1702, in __call__
    return self.func(*args)
  File "menu.py", line 32, in open_main
    root.destroy()
  File "c:\users\alireza\anaconda3\Lib\tkinter\__init__.py", line 2059, in destroy
    self.tk.call('destroy', self._w)
_tkinter.TclError: can't invoke "destroy" command: application has been destroyed

这是我的主菜单文件(menu.py):

from tkinter import *
import tkinter.messagebox


class Application:
    def __init__(self, master, *args, **kwargs):


        self.mainframe = Frame(master, width = 300, height = 400, bg = 'slategray1')
        self.mainframe.pack()

        self.main_button = Button (self.mainframe, width = 25, height = 2,bg = "SteelBlue2" , text = "Customer Service", command = self.open_main)
        self.main_button.place(x= 55, y =50 )

        self.add_to_db_button = Button (self.mainframe, width = 25, height = 2,bg = "SteelBlue2" , text = "Add Item To Inventory", command = self.open_add_to_db)
        self.add_to_db_button.place(x= 55, y =100 )

        self.update_button = Button (self.mainframe, width = 25, height = 2,bg = "SteelBlue2" , text = "Update Inventory Items", command = self.open_update)
        self.update_button.place(x= 55, y =150 )

        self.about_button = Button (self.mainframe, width = 25, height = 2,bg = "sea green" , text = "Credits", command = self.about)
        self.about_button.place(x= 55, y =300 )

        self.close_button = Button (self.mainframe, width = 25, height = 2,bg = "navajo white" , text = "Quit", command = self.close_window)
        self.close_button.place(x= 55, y =350 )

    def close_window(self, *args, **kwargs):
        root.destroy()

    def open_main(self, *args, **kwargs):
        import main
        root.destroy()

    def open_add_to_db(self, *args, **kwargs):
        import add_to_db
        root.destroy()

    def open_update(self, *args, **kwargs):
        from update import AppUpdate
        root.destroy()

    def about(self, *args, **kwargs):
        tkinter.messagebox.showinfo("About Me", "Programmed and designed by Alireza Bagheri.")


root = Tk()
root.title("Main Menu")
root.resizable(False, False)
b = Application(root)
root.geometry("301x401+0+0")
root.mainloop()

我不完全知道问题出在哪里,因此为我指明正确的方向意义重大

【问题讨论】:

  • 不要依赖import 为您打开窗口。主要问题是您的代码结构...如果您正在构建一个项目并且严重依赖imports,您应该始终将可执行代码包装在func_add_to_db() 等函数中,然后在open_add_to_db() 本身内调用func_add_to_db()。您的主要代码也应该被包裹在if __name__ == '__main__': 块中,以避免它们在import 处执行。您遇到的情况很可能是因为您始终destroy()ing 主应用程序,所以没有什么可以再次回到destroy()

标签: python windows tkinter frameworks


【解决方案1】:

正如 Idlehands 所评论的,我认为您不应该依赖 import main 来构建一个窗口,而是在 main 中定义一个函数(build_window() 也许?)然后您可以调用它,例如 @987654324 @。这将确保您知道应该执行什么代码,并可能有助于避免错误。我尝试运行您的代码,但无法复制错误,而是遇到以下错误:

  1. ImportError: No module named 'main'
  2. ImportError: No module named 'update'
  3. ImportError: No module named 'add_to_db'

因此,这不是您所面临错误的最低限度、可验证且完整的示例代码。我们能做的最多的就是推测一个解决方案。我的猜测是,如果你想“隐藏”一个稍后将返回的窗口,你应该 .iconify() 它将它最小化到任务栏。如果您在 Tkinter 小部件上调用 .destroy(),则该小部件将从内存中删除,如果您想要另一个小部件,则必须定义它,然后将 .pack().place().grid() 重新定义到屏幕上!我建议您阅读https://stackoverflow.com/help/mcve 以了解什么是最小、完整且可验证的示例。解决您的问题将使社区更容易为您提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-25
    • 2012-12-21
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多