为什么 tkinter 多制作 2 个窗口?

问题描述 投票:0回答:1

我正在 tkinter 中使用类来切换帧来制作游戏,但是每当我运行它时,我都会得到 2 个额外的窗口,其中一个在被破坏时会出现此错误:

Exception in Tkinter callback Traceback (most recent call last): File "D:\Thonny\lib\tkinter_init_.py", line 1921, in call return self.func(*args) File "D:\Thonny\lib\tkinter_init_.py", line 2342, in destroy Misc.destroy(self) File "D:\Thonny\lib\tkinter_init_.py", line 665, in destroy self.tk.deletecommand(name) _tkinter.TclError: can't delete Tcl command

我认为这可能是由于调用 Tk() 以及与 super() 和 init 有关,但我真的不知道它们做了什么 我的代码:

import tkinter as tk
from tkinter import *
from tkinter import ttk,font
from tkinter.messagebox import showinfo
from tkinter import messagebox
import shelve
from PIL import ImageTk,Image     #I know there are some that are probably unnescesary but
                                  #it works so i dont waant to touch it T.T

Game=Tk()

class Game(tk.Tk):
    def __init__(self):
        global background
        tk.Tk.__init__(self)
        super().__init__()
        self.geometry('992x558')
        background=ImageTk.PhotoImage(Image.open('background.png'),master=self)
        backgroundlabel= Label(self,image=background).place(x=0,y=0)
        self.iconbitmap('icon.ico')
        self._frame = None
        self.switchframe(npcheck)

    def switchframe(self, frameclass):
        newframe = frameclass(self)
        print(frameclass(self))
        if self._frame is not None:
            self._frame.destroy()            # destroy old frame
        self._frame = newframe             #set new frmae
        self._frame.grid()              ##draw new frame

class npcheck(tk.Frame):                #new player check
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        #tk.Frame.__init__(self, master,image=background)
        backgroundlabel= Label(self,image=background).place(x=0,y=0)
        q=Label(self, text= 'New or existing player?')
        q.grid(row=0,column=1,sticky=W+E,padx=50,pady=50)
        gobutton= Button(self,text='New Player.', command=lambda: master.switchframe(accountcreation))
        gobutton.grid(row=1,column=0,sticky=W,padx=50,pady=50)
        gobutton= Button(self,text='Existing Account.', command=lambda: master.switchframe(login))
        gobutton.grid(row=1,column=2,sticky=E,padx=50,pady=50)


if __name__ == "__main__":
    game = Game()
    game.mainloop()  

我尝试删除 Game=Tk() 并稍微摆弄它,但这只会破坏它更多 T.T

python windows tkinter
1个回答
0
投票

您获得了额外的窗口,因为您无意中多次实例化

Tk
(在整个代码的几个地方)。请注意,我已经注释掉或以其他方式禁用了背景图像内容,因为我手头没有这些文件。

我添加了一些关于约定/风格的注释(作为评论),但这应该按书面形式工作。

import tkinter as tk
from tkinter import ttk, font
from tkinter.messagebox import showinfo
# you're already importing something from messagebox above; if you need other
# methods from that module, just add them there
# from tkinter import messagebox
import shelve
from PIL import ImageTk, Image
# from tkinter import *  # it's best to avoid star imports. Instead, just access
# tk widgets like this: tk.Label, tk.Button, etc.

# Game=Tk()  # this is creating a window, but your Game class already
# inherits from tk.Tk, so you don't need to instantiate it here


class Game(tk.Tk):
    def __init__(self) -> None:
         # tk.Tk.__init__(self)  # you don't need this *and* super(), just use one - also, using both is creating yet another window!
        super().__init__()
        self.geometry('992x558')
        # background=ImageTk.PhotoImage(Image.open('background.png'),master=self)
        backgroundlabel=tk.Label(self,image=None).place(x=0,y=0)
        # self.iconbitmap('icon.ico')
        self._frame = None
        self.switchframe(npcheck)

    def switchframe(self, frameclass):
        newframe = frameclass(self)
        print(frameclass(self))
        if self._frame is not None:
            self._frame.destroy()            # destroy old frame
        self._frame = newframe             #set new frmae
        self._frame.grid()              ##draw new frame


class npcheck(tk.Frame):  # this should be capitalized, e.g. NpcCheck              #new player check
    def __init__(self, master):
        tk.Frame.__init__(self, master)  # you can use super() here too!
        # super().__init__(master)  # like this
        #tk.Frame.__init__(self, master,image=background)
        backgroundlabel= tk.Label(self,image=None).place(x=0,y=0)
        q=tk.Label(self, text= 'New or existing player?')
        q.grid(row=0,column=1,sticky='ew',padx=50,pady=50)
        gobutton= tk.Button(self,text='New Player.', command=lambda: master.switchframe(accountcreation))
        gobutton.grid(row=1,column=0,sticky='w',padx=50,pady=50)
        gobutton= tk.Button(self,text='Existing Account.', command=lambda: master.switchframe(login))
        gobutton.grid(row=1,column=2,sticky='e',padx=50,pady=50)


if __name__ == "__main__":
    game = Game()
    game.mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.