【问题标题】:Why does destroy() not work in this code?为什么destroy() 在这段代码中不起作用?
【发布时间】:2018-03-08 08:34:55
【问题描述】:

这是我正在尝试编写的一个简单的测试脚本,它将帮助我自学 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()

当我运行这段代码时它返回一个错误?

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

为什么这不起作用以及如何解决?

在此先感谢 :) (顺便说一句,我使用的是 python 3.6)

【问题讨论】:

  • 这是您的完整代码吗?您从未将窗口 1 和窗口 2 设置为 None 以外的任何内容(我忽略了什么吗?)这可能是问题
  • @FlyingTeller 是的,这是完整的代码......我将如何设置它们同时仍然允许 setWindow() 等函数工作?
  • 等一下,写一个更详细的答案
  • 这个错误从字面上回答了标题中的问题。

标签: python python-3.x tkinter destroy


【解决方案1】:

你设置

window2 = None
window1 = None

作为全局变量,然后定义button2的命令函数为

lambda: newScreen(window2, window1)

调用newScreen 的值window2 和window1 都是None,因此出现错误。这里的根本问题是你的setWindow 函数:

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

这与您使用它的方式不同。当您调用setWindow(window1) 时,您传递了window1,函数对变量所做的操作在全局范围内是看不到的。一个简单的例子是这样的:

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

这将打印 1 两次。

为了实现你想要的,我建议你使用字典来跟踪你的窗口。

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()

附注:之前你的函数是def newScreen(newScreen, screenToDelete),这是非常混乱/糟糕的风格,因为函数和它的第一个参数共享相同的名称。无论如何,我更改了它以强调它现在将字符串作为参数,但请记住它以备将来使用。

【讨论】:

  • 非常感谢!现在我可以继续我的任务了!
  • @Jake 不客气。记下我刚刚所做的两个编辑。
【解决方案2】:

我现在无法对其进行测试,但我发现了错误来源:

lambda: newScreen(window2, window1)

这会创建一个不带任何参数的 lambda 函数,因此 window2 和 window1 将为 None,并且 None 没有 destroy() 方法,因此会出现错误。而是尝试:

lambda window2, window1: newScreen(window2, window1)

【讨论】:

  • 返回错误:TypeError: () missing 2 required positional arguments: 'window2' and 'window1'
  • 啊,是的,当然,我冲过去了,应该已经测试过了。 @FlyingTeller 给出了很好的答案。
猜你喜欢
  • 2010-09-18
相关资源
最近更新 更多