简体   繁体   中英

Why does destroy() not work in this code?

This is a simple test script I am attempting to write which will help me teach myself about tkinter...

from tkinter import *
def hello():
   print("U pressed it lol")

global window1, window2
window2 = None
window1 = None

def setWindow(windowEnter):
   global window
   window = windowEnter
   window = Tk()
   window.attributes("-fullscreen", True)

def newScreen(newScreen, screenToDelete):
   setWindow(newScreen)
   print("New Window Created")
   screenToDelete.destroy()
   print("He ded lol")

setWindow(window1)

def setStuff():
   button = Button(window1, text="hey", command=hello)
   label = Label(window1, text="YoYoYo My dude")
   button2 = Button(window1, text="Next Page", command = lambda: newScreen(window2, window1))

   button.pack()
   label.pack()
   button2.pack()

setStuff()

When I run this code it returns an error?

File "C:\Users\026341\Desktop\test.py", line 19, in newScreen
screenToDelete.destroy()
AttributeError: 'NoneType' object has no attribute 'destroy'

Why doesn't this work & how do i fix it?

Thanks in advance :) (Btw I'm using python 3.6)

You set

window2 = None
window1 = None

as global variables and then define the command function for button2 to be

lambda: newScreen(window2, window1)

Which calls newScreen with the values window2 and window1 which are both None , hence the error. The underlying issue here is your setWindow function:

def setWindow(windowEnter):
    global window
    window = windowEnter
    window = Tk()
    window.attributes("-fullscreen", True)

which doesn't work the way you are using it. When you call setWindow(window1) , you pass the value of window1 , what the function does with the variable cannot be seen on a global scope. A quick example would be this:

def increment(a):
    a +=1
x = 1
print(x)
increment(x)
print(x)

which will print 1 twice.

To achieve what you want I suggest you use a dictionary to keep track of your windows.

from tkinter import *
def hello():
   print("U pressed it lol")

global window1, window2
windows = {}


def setWindow(window_name):
   windows[window_name] = Tk()
   windows[window_name].attributes("-fullscreen", True)

def newScreen(newScreen_name, screenToDelete_name):
   setWindow(newScreen_name)
   print("New Window Created")
   windows[screenToDelete_name].destroy()
   del windows[screenToDelete_name] #delete invalid entry from dict
   print("He ded lol")

setWindow("window1")

def setStuff():
   button = Button(windows["window1"], text="hey", command=hello)
   label = Label(windows["window1"], text="YoYoYo My dude")
   button2 = Button(windows["window1"], text="Next Page", command = lambda: newScreen("window2", "window1"))

   button.pack()
   label.pack()
   button2.pack()

setStuff()

Note on the side: previously your function was def newScreen(newScreen, screenToDelete) , which is very confusing/bad style since both the function and its first argument share the same name. I changed it anyway to highlight that it now takes strings as arguments, but keep it in mind for the furture.

I'm not able to test it right now, but I've spotted a source of error:

lambda: newScreen(window2, window1)

This creates a lambda function that doesn't take any arguments, hence window2 and window1 will be None, and None doesn't have a destroy() method, hence the error. Instead try:

lambda window2, window1: newScreen(window2, window1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM