初衷
最近在用python tkinter做GUI界面项目。项目分多个模块,多人配合,最后整合到主界面上。
为了避免大篇幅修改主界面,采用批量加菜单栏的方式设定主界面,只要配置GUIdict就能完成主界面与模块界面的关联,十分方便。
思路
- 首先分析主界面菜单栏生成的模式,最简单的方法是:
menubar = tk.Menu(root)
menubar.add_command(command='按钮对应的控制函数',
label='按钮的显示名称',{'其他参数诸如颜色字体等':'...'})
root['menu'] = menubar#指定主窗口的'menu'属性为刚刚创建的menubar
其中的add_command以退出键为例:
args = {'background':"#ffff00",
'font':"TkMenuFont",
'foreground':"#000000"}
def quit():
root.destroy()
menubar.add_command(
command=quit,
label="Quit",**args)
- 批量添加菜单栏的问题转化成批量读取“按钮的显示名称”和“按钮对应的控制函数”。为此,设定一个GUIdict包含{“按钮的显示名称”:“按钮对应的控制函数”}。
- 关于按钮对应的控制函数:
- 各模块控制函数大家约定好,以xxgui.start( ∗ ∗ a r g s **args ∗∗args)来实现即可。
- 为了不影响从主函数中传入 ∗ ∗ a r g s **args ∗∗args,把模块控制函数转成func = xxgui.start ,调用时采用func( ∗ ∗ a r g s **args ∗∗args)方式。为了批量写成eval(’%s.start’%模块类名),配合使用时菜单按钮的command=lambda:start_func(self.root,self.maindata,self.info)。【lambda式是保证正常运行,否则command接收到的将是start_func(self.root,self.maindata,self.info)的运行结果而报错】
- 于是GUIdict包含{“按钮的显示名称”:eval(’%s.start’%模块类名)}
python tkinter实现
class appGUI:
def __init__(self):
pass
@staticmethod
def start(*args):
pass
class appGUI2:
def __init__(self):
pass
@staticmethod
def start(*args):
pass
#GUIdict = {"按钮的显示名称":eval('%s.start'%模块类名)}
GUIdict = {"app":eval('%s.start'%'appGUI'),
"app2":eval('%s.start'%'appGUI2')}
class mainGUI:
def __init__(self,maindata):
self.maindata = maindata
self.root = tk.Tk()
self.menubar = tk.Menu(self.root,bg='#ff0000',fg='#000000')
#基于GUIdict添加各模块对应按钮
args = {'activebackground':"#d9d9d9",
'activeforeground':"#000000",
'background':"#ffff00",
'font':"TkMenuFont",
'foreground':"#000000"}
for name,start_func in GUIdict.items():
self.menubar.add_command(
command=lambda:start_func(self.root,self.maindata),
label=name,**args)
self.root['menu'] = self.menubar#指定主窗口的'menu'属性为刚刚创建的menubar
self.root.mainloop()
if __name__ =='__main__':
mainGUI()