Python Tkinter:如何在不断变化的 class 中避免使用全局变量?
Python Tkinter: How do I avoid global variables in a changing class?
我目前正在做一个大型项目来帮助我学习我的第一门编程语言 (Python),并且我 运行 进入了一些未知的领域。我知道使用全局变量通常是不好的并且有更好的解决方案,但我无法根据我的情况弄清楚。
我将下面的代码作为我想要实现的目标的简单示例。执行此操作而不是使用全局变量的最佳方法是什么?
此外,我在下面的代码中是否犯了任何一般性错误?
提前致谢
from tkinter import *
root = Tk()
display_number = 5
class NumberBox():
def __init__(self):
global display_number
self.number_label = Label(root, text=display_number)
self.number_label.pack()
self.engine()
def engine(self):
self.number_label.config(text=display_number)
root.after(10, self.engine)
def change_number(operation):
global display_number
if operation == "add":
display_number += 1
if operation == "subtract":
display_number -= 1
Button(root, text="Add Class", command=lambda: NumberBox()).pack()
Button(root, text="Number UP", command=lambda: change_number("add")).pack()
Button(root, text="Number DOWN", command=lambda: change_number("subtract")).pack()
for _ in range(5):
NumberBox()
root.mainloop()
像这样:
from tkinter import *
root = Tk()
class NumberBox():
display_number = 5
def __init__(self):
self.number_label = Label(root, text=self.display_number)
self.number_label.pack()
self.engine()
def engine(self):
self.number_label.config(text=self.display_number)
root.after(10, self.engine)
def change_number(operation):
if operation == "add":
NumberBox.display_number += 1
if operation == "subtract":
NumberBox.display_number -= 1
Button(root, text="Add Class", command=lambda: NumberBox()).pack()
Button(root, text="Number UP", command=lambda: change_number("add")).pack()
Button(root, text="Number DOWN", command=lambda: change_number("subtract")).pack()
for _ in range(5):
NumberBox()
root.mainloop()
通过在 class 中定义变量(但在 __init__
之外,它作为单个变量由 class 的所有实例拥有,因此在一个变量中更改它会影响所有实例
我做了几处修改:
- 创建一个新的 class NumberBoxesList 以避免全局变量并使程序的逻辑更加可见
- 删除
root.after
方法:此方法不应用于在用户操作后立即进行更新
- 使用
import tkinter as tk
:import *
是不好的做法
结果:
import tkinter as tk
class NumberBox():
def __init__(self, root, display_number):
self.number_label = tk.Label(root, text=display_number)
self.number_label.pack()
def changeNumber(self, display_number):
self.number_label.config(text=display_number)
class NumberBoxesList():
def __init__(self, root, start_number = 5):
self.number = start_number
self.root = root
self.boxes = []
tk.Button(root, text="Add Class", command= self.addBox).pack()
tk.Button(root, text="Number UP", command=lambda: self.change_number("add")).pack()
tk.Button(root, text="Number DOWN", command=lambda: self.change_number("subtract")).pack()
def addBox(self):
self.boxes.append(NumberBox(self.root, self.number))
def change_number(self, operation):
if operation == "add":
self.number += 1
if operation == "subtract":
self.number -= 1
for box in self.boxes:
box.changeNumber(self.number)
root = tk.Tk()
boxList = NumberBoxesList(root)
for _ in range(5):
boxList.addBox()
root.mainloop()
我目前正在做一个大型项目来帮助我学习我的第一门编程语言 (Python),并且我 运行 进入了一些未知的领域。我知道使用全局变量通常是不好的并且有更好的解决方案,但我无法根据我的情况弄清楚。
我将下面的代码作为我想要实现的目标的简单示例。执行此操作而不是使用全局变量的最佳方法是什么?
此外,我在下面的代码中是否犯了任何一般性错误?
提前致谢
from tkinter import *
root = Tk()
display_number = 5
class NumberBox():
def __init__(self):
global display_number
self.number_label = Label(root, text=display_number)
self.number_label.pack()
self.engine()
def engine(self):
self.number_label.config(text=display_number)
root.after(10, self.engine)
def change_number(operation):
global display_number
if operation == "add":
display_number += 1
if operation == "subtract":
display_number -= 1
Button(root, text="Add Class", command=lambda: NumberBox()).pack()
Button(root, text="Number UP", command=lambda: change_number("add")).pack()
Button(root, text="Number DOWN", command=lambda: change_number("subtract")).pack()
for _ in range(5):
NumberBox()
root.mainloop()
像这样:
from tkinter import *
root = Tk()
class NumberBox():
display_number = 5
def __init__(self):
self.number_label = Label(root, text=self.display_number)
self.number_label.pack()
self.engine()
def engine(self):
self.number_label.config(text=self.display_number)
root.after(10, self.engine)
def change_number(operation):
if operation == "add":
NumberBox.display_number += 1
if operation == "subtract":
NumberBox.display_number -= 1
Button(root, text="Add Class", command=lambda: NumberBox()).pack()
Button(root, text="Number UP", command=lambda: change_number("add")).pack()
Button(root, text="Number DOWN", command=lambda: change_number("subtract")).pack()
for _ in range(5):
NumberBox()
root.mainloop()
通过在 class 中定义变量(但在 __init__
之外,它作为单个变量由 class 的所有实例拥有,因此在一个变量中更改它会影响所有实例
我做了几处修改:
- 创建一个新的 class NumberBoxesList 以避免全局变量并使程序的逻辑更加可见
- 删除
root.after
方法:此方法不应用于在用户操作后立即进行更新 - 使用
import tkinter as tk
:import *
是不好的做法
结果:
import tkinter as tk
class NumberBox():
def __init__(self, root, display_number):
self.number_label = tk.Label(root, text=display_number)
self.number_label.pack()
def changeNumber(self, display_number):
self.number_label.config(text=display_number)
class NumberBoxesList():
def __init__(self, root, start_number = 5):
self.number = start_number
self.root = root
self.boxes = []
tk.Button(root, text="Add Class", command= self.addBox).pack()
tk.Button(root, text="Number UP", command=lambda: self.change_number("add")).pack()
tk.Button(root, text="Number DOWN", command=lambda: self.change_number("subtract")).pack()
def addBox(self):
self.boxes.append(NumberBox(self.root, self.number))
def change_number(self, operation):
if operation == "add":
self.number += 1
if operation == "subtract":
self.number -= 1
for box in self.boxes:
box.changeNumber(self.number)
root = tk.Tk()
boxList = NumberBoxesList(root)
for _ in range(5):
boxList.addBox()
root.mainloop()