在Python GUI中更改按钮颜色
import sys
from tkinter import *
def run_GUI():
# create the window
root = Tk()
frame = Frame(root)
frame.pack()
#modify root window
root.title("Simple GUI")
root.geometry("700x300") # w x h
def SP2T(): # Edit occurs here where I forgot to pit that the button was created in a called funtction
#Creates Row
frameSP2T = Frame(root)
frameSP2T.pack(side = TOP)
#Creating Buttons First Row
button1 = Button(frameSP2T, padx=13, pady = 6, bd=4, text="SW02",fg = "black", command = SW02)
button1.pack(side = LEFT)
def SW02():
print("SW02 is on")
button1["fg"] = "green"
#Sets up initial boot screen
#Creates Row
topframe = Frame(root)
topframe.pack(side = TOP)
#Creating Buttons First Row
buttonA = Button(topframe, padx=13, pady = 6, bd=4, text="SP2T",fg = "black", command = SP2T)
buttonA.pack(side = LEFT)
buttonB = Button(topframe, padx=12, pady = 6, bd=4, text="SP4T",fg = "black")
buttonB.pack(side = LEFT)
buttonC = Button(topframe, padx=12, pady = 6, bd=4, text="SP12T",fg = "black")
buttonC.pack(side = LEFT)
buttonD = Button(topframe, padx=12, pady = 6, bd=4, text="QUIT", fg="red",command=frame.quit)
buttonD.pack(side = LEFT)
#Kick off event loop
root.mainloop()
return
run_GUI()
我遇到了这个错误:
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
return self.func(*args)
File "C:\Python34\gui_attempt.py", line 25, in SW02
button1["fg"] = "green"
NameError: name 'button1' is not defined
这是更新后的版本,希望能展示整个情况
这个程序还有更多内容,所以提到的是第60行,但这里是问题所在。我想在按钮被按下时改变它的颜色。
2 个回答
0
你遇到了一个关于作用域
的问题。这个错误发生在SW02()
这个函数里,因为你试图修改一个不在这个函数范围内的对象。你需要把这个对象传递进来。把SW02()
改成下面这样:
def SW02(button1):
print("SW02 is on")
button1["fg"] = "green"
因为你把这个函数当作命令的动作,所以你有几种方法可以把对象传递进去。
可以使用一个lambda
表达式:
button1 = Button(frameSP2T, padx=13, pady = 6, bd=4, text="SW02",fg = "black", command = lambda: SW02(button1))
也可以使用functools.partial
:
from functools import partial
# other stuff
_SW02 = partial(SW02, button1)
button = Button(frameSP2T, padx=13, pady = 6, bd=4, text="SW02",fg="black", command=_SW02)
另外,正如jonrsharpe的回答中提到的,你可以把整个图形用户界面(GUI)函数重构成一个类,把所有的控件作为类的成员,然后把控件的操作和类的方法关联起来,而不是用普通的函数。这样,所有修改GUI组件的函数都能访问到这些组件。
2
最简单的解决办法是在需要访问那个对象的两个函数开头加上 global button
。
def SP2T():
global button1
...
def SW02():
global button1
...
不过,使用 global
通常不是个好主意——你可以考虑用面向对象的方法,像下面这个简单的例子:
import tkinter as tk
class MyGui(tk.Tk):
def __init__(self):
super(MyGui, self).__init__()
self.create_widgets()
def create_widgets(self):
self.frame = tk.Frame(self)
self.frame.pack()
self.buttonA = tk.Button(self.frame, padx=13, pady=6, bd=4, text="SP2T",
fg="black", command=self.SP2T)
self.buttonA.pack(side=tk.LEFT)
def SW02(self):
print("SW02 is on")
self.button1["fg"] = "green"
def SP2T(self):
self.button1 = tk.Button(self.frame, padx=13, pady=6, bd=4, text="SW02",
fg="black", command=self.SW02)
self.button1.pack(side=tk.LEFT)
if __name__ == "__main__":
root = MyGui()
root.mainloop()