我的第一个Python / Tkinter项目是1000行。时间有些指示让我走在路上。 所以我想最初禁用显示布局按钮(灰色)。加载文件后,显示布局处于活动状态。
def ReadFile()
#Something Magical Happens
Layoutbutton.config(state='active')
def DisplayLayout()
#Draw Great gobs of stuff
def main()
global Layoutbutton
#setup root window yada yada yada
Layoutbutton=Button(root,text="Layout",command=DisplayLayout,underline=0)
Layoutbutton.place(relx=.5,rely=.85,anchor=CENTER)
root.bind("l",DisplayLayout)
root.bind('L',DisplayLayout)
Layoutbutton.config(state='disabled')
BrowesButton=Button(root,text="File",command=ReadFile,underline=0)
BrowesButton.place(relx=.75,rely=.85,anchor=CENTER)
root.bind("F",ReadFile)
root.bind('f',ReadFile)
if __name__ == '__main__':
root=Tk()
main()
这一切都按预期工作。在读取文件之前,将显示DisplayLayout按钮。
我质疑全局LayoutButton的使用。我有很多此类事情正在发生。 如果(没有更好的术语)兄弟窗口如何在没有太多全局变量的情况下相互通信?
答案 0 :(得分:1)
使函数ReadFile
接受参数:
def ReadFile(LayoutButton):
#Something Magical Happens
LayoutButton.config(state='active')
在main
内定义一个用ReadFile
调用LayoutButton
的函数。用新的功能替换ReadFile
的出现。
def main():
#global Layoutbutton # No need to declare LayoutButton as global.
def wrapper(event=None): # <-------
return ReadFile(Layoutbutton) # <-------
#setup root window yada yada yada
Layoutbutton=Button(root,text="Layout",command=wrapper,underline=0) # <--
Layoutbutton.place(relx=.5,rely=.85,anchor=CENTER)
root.bind("l",DisplayLayout)
root.bind('L',DisplayLayout)
Layoutbutton.config(state='disabled')
BrowesButton=Button(root,text="File",command=wrapper,underline=0) # <--
BrowesButton.place(relx=.75,rely=.85,anchor=CENTER)
root.bind("F", wrapper) # <-------
root.bind('f', wrapper) # <-------
或者,您可以使用lambda
代替函数:
wrapper = lambda event=None: ReadFile(Layoutbutton).
或者使用类构建程序。
答案 1 :(得分:0)
你可以通过客观化你的代码来绕过使用全局变量。例如,您的示例的不同实现可能是:
def read_file():
#magic happens
class MyFrame(object):
def __init__(self,parent):
self.parent = parent
self.layout_button = Button(self.parent,text="Layout",
command=self.display_layout,underline=0)
self.layout_button.place(relx=.5,rely=.85,anchor=CENTER)
self.parent.bind("l",self.display_layout)
self.parent.bind('L',self.display_layout)
self.layout_button.config(state='disabled')
self.browes_button=Button(self.parent,text="File",
command=self._call_read_file,underline=0)
self.browes_button.place(relx=.75,rely=.85,anchor=CENTER)
self.parent.bind("F",self._call_read_file)
self.parent.bind('f',self._call_read_file)
def display_layout(self):
#populate frame etc.
def _call_read_file(self):
read_file()
self.layout_button.config(state='active')
def main(root):
frame = MyFrame(root)
root.mainloop()
if __name__ == "__main__":
root = Tk()
main(root)
这可能是个人偏好,但我发现GUI设计更加直观,与大量使用全局变量的代码相比,更容易追踪不需要的行为。通过这种方法,每个帧都保持对其父帧的引用,实质上是在所有帧需要进行更新时相互访问。一个完整且相当愚蠢的例子可能是:
import Tkinter as tk
class MyOtherFrame(object):
def __init__(self,parent):
self.root = parent
self.enable_button = tk.Button(self.root,text="enable",command=self.enable)
self.enable_button.pack()
self.disable_button = tk.Button(self.root,text="disable",command=self.disable)
self.disable_button.pack()
self.child_frame = tk.Frame(self.root)
self.child_frame.pack()
self.child_frame_obj = MyFrame(self.child_frame)
def enable(self):
self.child_frame_obj.button.config(state="active")
def disable(self):
self.child_frame_obj.button.config(state="disabled")
class MyFrame(object):
def __init__(self,parent):
self.root = parent
self.button = tk.Button(self.root,text="useless button")
self.button.pack()
def main():
root = tk.Tk()
x = MyOtherFrame(root)
root.mainloop()
if __name__ == "__main__":
main()