我是python的新手,我正在尝试动态更改按钮的文本和命令来制作子菜单。 这是我的代码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import tkinter
class Display(tkinter.Tk):
def __init__(self,parent):
tkinter.Tk.__init__(self,parent)
self.parent = parent
self.GuiDisplay()
def GuiDisplay(self):
self.grid()
self.geometry("1280x720")
#self.overrideredirect(True) #uncomment for fullscreen
"""Build the GUI"""
MessageDisplay = tkinter.Label(self, text = 'No messages from slaves', anchor = 'nw', justify = 'left', relief = 'ridge', font = ("Courier New", 15), bg = '#e4e7e8', fg = '#2980b9')
MessageDisplay.grid(row = 0, column = 0, columnspan = 3, sticky = 'wens', ipadx = 2, ipady = 2)
ClockDisplay = tkinter.Label(self, text = '00:00', relief = 'ridge', font = ("Courier New", 40), bg = '#e4e7e8', fg = '#2980b9')
ClockDisplay.grid(row = 0, column = 3, sticky = 'wens', ipadx = 2, ipady = 2)
Menu1Button = tkinter.Button(self, text = 'Ring', command = self.Action(Do = 'Rng'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
Menu1Button.grid(row = 1, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
Menu2Button = tkinter.Button(self, text = 'Toggle holliday mode', command = self.Action(Do = 'SwHolDay'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
Menu2Button.grid(row = 2, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
Menu3Button = tkinter.Button(self, text = 'Edit time', command = self.SetMenu(MenuIndex = 2), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
Menu3Button.grid(row = 3, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
Menu4Button = tkinter.Button(self, text = 'Add/Edit alarms', command = self.SetMenu(MenuIndex = 3), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
Menu4Button.grid(row = 4, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
Menu5Button = tkinter.Button(self, text = 'Shutdown', command = self.Action(Do = 'Shutdwn'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
Menu5Button.grid(row = 5, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
MenuDescription = tkinter.Label(self, text = 'No menu selected.', anchor = 'nw', justify = 'left', relief = 'ridge', font = ("Courier New", 15), bg = '#e4e7e8', fg = '#2980b9')
MenuDescription.grid(column = 2, columnspan = 2, row = 1, rowspan = 5, sticky = 'wens', ipadx = 2, ipady = 2)
self.grid_columnconfigure(0, weight = 3)
self.grid_columnconfigure(1, weight = 3)
self.grid_columnconfigure(2, weight = 3)
self.grid_columnconfigure(3, weight = 1)
self.grid_rowconfigure(0, weight = 10)
self.grid_rowconfigure(1, weight = 18)
self.grid_rowconfigure(2, weight = 18)
self.grid_rowconfigure(3, weight = 18)
self.grid_rowconfigure(4, weight = 18)
self.grid_rowconfigure(5, weight = 18)
def SetMenu(self, MenuIndex):
if MenuIndex==1:
self.Menu1Button.configure(text = 'Ring', command = self.Action(Do = 'Rng'))
self.Menu2Button.configure(text = 'Toggle holliday mode', command = self.Action(Do = 'SwHolDay'))
self.Menu3Button.configure(text = 'Edit time', command = self.SetMenu(MenuIndex = 2))
self.Menu4Button.configure(text = 'Add/Edit alarms', command = self.SetMenu(MenuIndex = 3))
self.Menu5Button.configure(text = 'Shutdown', command = self.Action(Do = 'Shutdwn'))
elif MenuIndex==2:
self.Menu1Button.configure(text = 'Edit hours', command = self.Action(Do = 'ModH'))
self.Menu2Button.configure(text = 'Edit minutes', command = self.Action(Do = 'ModM'))
self.Menu3Button.configure(text = 'Edit seconds', command = self.Action(Do = 'ModS'))
self.Menu4Button.configure(text = 'Internet synchronization', command = self.Action(Do = 'Synch'))
self.Menu5Button.configure(text = 'Return to menu', command = self.SetMenu(MenuIndex = 1))
elif MenuIndex==3:
self.Menu1Button.configure(text = 'Edit hours', command = self.Action(Do = 'ModHA'))
self.Menu2Button.configure(text = 'Edit minutes', command = self.Action(Do = 'ModMA'))
self.Menu3Button.configure(text = 'Edit seconds', command = self.Action(Do = 'ModSA'))
self.Menu4Button.configure(text = 'Switch mode', command = self.Action(Do = 'ChMod'))
self.Menu5Button.configure(text = 'Return to menu', command = self.SetMenu(MenuIndex = 1))
def Action(self, Do):
pass
if __name__ == "__main__":
app = Display(None)
app.title('Web Bell')
app.mainloop()
并且错误的回溯是
File "\\uranus\faure\Bureau\project\webBell.py", line 80, in <module>
app = Display(None)
File "\\uranus\faure\Bureau\project\webBell.py", line 10, in __init__
self.GuiDisplay()
File "\\uranus\faure\Bureau\project\webBell.py", line 32, in GuiDisplay
Menu3Button = tkinter.Button(self, text = 'Edit time', command = self.SetMenu(MenuIndex = 2), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
File "\\uranus\faure\Bureau\project\webBell.py", line 64, in SetMenu
self.Menu1Button.configure(text = 'Edit hours', command = self.Action(Do = 'ModH'))
File "C:\Python33\lib\tkinter\__init__.py", line 1867, in __getattr__
return getattr(self.tk, attr)
AttributeError: 'tkapp' object has no attribute 'Menu1Button'
我猜它来自SetMenu函数中的“self”,但是我试过没有它仍然没有用。
编辑: 更新的代码
#!/usr/bin/python
# -*- coding: utf-8 -*-
import tkinter
class Display(tkinter.Tk):
def __init__(self,parent):
tkinter.Tk.__init__(self,parent)
self.parent = parent
self.GuiDisplay()
def GuiDisplay(self):
self.grid()
self.geometry("1280x720")
#self.overrideredirect(True) #uncomment for fullscreen
"""Build the GUI"""
self.MessageDisplay = tkinter.Label(self, text = 'No messages from slaves', anchor = 'nw', justify = 'left', relief = 'ridge', font = ("Courier New", 15), bg = '#e4e7e8', fg = '#2980b9')
self.MessageDisplay.grid(row = 0, column = 0, columnspan = 3, sticky = 'wens', ipadx = 2, ipady = 2)
self.ClockDisplay = tkinter.Label(self, text = '00:00', relief = 'ridge', font = ("Courier New", 40), bg = '#e4e7e8', fg = '#2980b9')
self.ClockDisplay.grid(row = 0, column = 3, sticky = 'wens', ipadx = 2, ipady = 2)
self.Menu1Button = tkinter.Button(self, text = 'Ring', command = self.Action(Do = 'Rng'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
self.Menu1Button.grid(row = 1, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
self.Menu2Button = tkinter.Button(self, text = 'Toggle holliday mode', command = self.Action(Do = 'SwHolDay'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
self.Menu2Button.grid(row = 2, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
self.Menu3Button = tkinter.Button(self, text = 'Edit time', command = self.SetMenu(MenuIndex = 2), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
self.Menu3Button.grid(row = 3, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
self.Menu4Button = tkinter.Button(self, text = 'Add/Edit alarms', command = self.SetMenu(MenuIndex = 3), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
self.Menu4Button.grid(row = 4, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
self.Menu5Button = tkinter.Button(self, text = 'Shutdown', command = self.Action(Do = 'Shutdwn'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
self.Menu5Button.grid(row = 5, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
self.MenuDescription = tkinter.Label(self, text = 'No menu selected.', anchor = 'nw', justify = 'left', relief = 'ridge', font = ("Courier New", 15), bg = '#e4e7e8', fg = '#2980b9')
self.MenuDescription.grid(column = 2, columnspan = 2, row = 1, rowspan = 5, sticky = 'wens', ipadx = 2, ipady = 2)
self.grid_columnconfigure(0, weight = 3)
self.grid_columnconfigure(1, weight = 3)
self.grid_columnconfigure(2, weight = 3)
self.grid_columnconfigure(3, weight = 1)
self.grid_rowconfigure(0, weight = 10)
self.grid_rowconfigure(1, weight = 18)
self.grid_rowconfigure(2, weight = 18)
self.grid_rowconfigure(3, weight = 18)
self.grid_rowconfigure(4, weight = 18)
self.grid_rowconfigure(5, weight = 18)
def SetMenu(self, MenuIndex):
if MenuIndex==1:
self.Menu1Button.configure(text = 'Ring', command = self.Action(Do = 'Rng'))
self.Menu2Button.configure(text = 'Toggle holliday mode', command = self.Action(Do = 'SwHolDay'))
self.Menu3Button.configure(text = 'Edit time', command = self.SetMenu(MenuIndex = 2))
self.Menu4Button.configure(text = 'Add/Edit alarms', command = self.SetMenu(MenuIndex = 3))
self.Menu5Button.configure(text = 'Shutdown', command = self.Action(Do = 'Shutdwn'))
elif MenuIndex==2:
self.Menu1Button.configure(text = 'Edit hours', command = self.Action(Do = 'ModH'))
self.Menu2Button.configure(text = 'Edit minutes', command = self.Action(Do = 'ModM'))
self.Menu3Button.configure(text = 'Edit seconds', command = self.Action(Do = 'ModS'))
self.Menu4Button.configure(text = 'Internet synchronization', command = self.Action(Do = 'Synch'))
self.Menu5Button.configure(text = 'Return to menu', command = self.SetMenu(MenuIndex = 1))
elif MenuIndex==3:
self.Menu1Button.configure(text = 'Edit hours', command = self.Action(Do = 'ModHA'))
self.Menu2Button.configure(text = 'Edit minutes', command = self.Action(Do = 'ModMA'))
self.Menu3Button.configure(text = 'Edit seconds', command = self.Action(Do = 'ModSA'))
self.Menu4Button.configure(text = 'Switch mode', command = self.Action(Do = 'ChMod'))
self.Menu5Button.configure(text = 'Return to menu', command = self.SetMenu(MenuIndex = 1))
def Action(self, Do):
pass
if __name__ == "__main__":
app = Display(None)
app.title('Web Bell')
app.mainloop()
答案 0 :(得分:2)
您尚未将Menu1Button
定义为类属性,因此它仅限于__init__
内。它应该定义为:
self.Menu1Button = tkinter.Button(self, text = 'Ring', command = self.Action(Do = 'Rng'), font = ("Courier New", 20), bg = '#3498db', fg = '#e4e7e8', activebackground = '#2980b9', activeforeground = '#e4e7e8')
self.Menu1Button.grid(row = 1, column = 0, columnspan = 2, sticky = 'wens', padx = 2, ipadx = 4)
构造函数中定义的所有其他小部件也是如此。
编辑:
现在,第一个问题得到解决,问题变得更加清晰。您正在错误地定义窗口小部件的命令属性。
例如,对于self.Menu3Button
,您将命令定义为self.SetMenu(MenuIndex = 2)
。在python中,这将尝试使用参数self.SetMenu
执行函数2
(侧栏:您不需要MenuIndex=2
,只需2
就可以了)得到它。这会导致函数SetMenu
在Menu3Button
被定义为类属性之前执行。因此python找不到该属性,你得到AttributeError
。
传递给窗口小部件的command
应该是一个函数实例。例如:
# an example function
def printit(val):
print val
# This is NOT valid
command = printit("hello!")
# This is valid
command = lambda:printit("hello!")
在有效的情况下,我们传递的是部分函数(即已经附加参数的半成形函数):
In [29]: printit("direct call")
direct call
In [30]: partial_printit = lambda:printit("partial call")
In [31]: partial_printit()
partial call
所以在你的情况下:
command = self.SetMenu(MenuIndex = 2)
变为
command = lambda:self.SetMenu(MenuIndex = 2)
对于所有小部件的所有command
个关键字都是如此。
有关lambda函数的更多信息,请参见此处:https://docs.python.org/2/tutorial/controlflow.html#lambda-expressions