Python界面程式设计Tkinter建立选单:视窗选单、工具选单、右键选单
本节介绍Python使用者界面程式设计,如何使用Tkinter库建立各种选单:视窗选单、工具栏选单、右键选单等,并有对应的程式码示例!
Python tkinter 视窗选单、工具选单、右键选单
视窗选单
Tkinter 为建立选单提供Menu 类,该类既能实现选单,又能实现上下文选单(右键选单)
Menu类建立选单提供相关方法:
add_cascade() 新增选单add_command() 新增选单项add_checkbutton() 新增复选框选单项add_radiobutton() 新增单选钮选单项add_separator() 新增选单分隔条方法对应引数:
label:指定选单项的文字command:为选单项系结的事件处理函式image:指定选单项的图示compound:指定选单项中图示位于文字的哪个方位使用Menu建立视窗选单示例:
# -*- coding:utf-8 -*-
from tkinter import *
# 汇入ttk
from tkinter import ttk
from tkinter import messagebox
class App(object):
def __init__(self, mw):
self.mw = mw
self.init_menu()
def init_menu(self):
self.filenew_icon = PhotoImage(file=\'image/filenew.png\')
self.fileopen_icon = PhotoImage(file=\'image/fileopen.png\')
menubar = Menu(self.mw)
# 将menu设定为视窗的选单条
self.mw[\'menu\'] = menubar
# 建立file_menu选单,并放入menubar中
file_menu = Menu(menubar, tearoff=0)
# 新增file_menu选单
menubar.add_cascade(label=\'档案\', menu=file_menu)
# file_menu新增选单项
file_menu.add_command(label="新建", command = None,image=self.filenew_icon, compound=LEFT)
file_menu.add_command(label="开启", command = None,image=self.fileopen_icon, compound=LEFT)
# 为file_menu新增分隔条
file_menu.add_separator()
# 为file_menu建立子选单
sub_menu = Menu(file_menu, tearoff=0)
# 新增sub_menu子选单
file_menu.add_cascade(label=\'选择性别\', menu=sub_menu)
self.genderVar = StringVar()
# 为sub_menu子选单新增选单项
for im in [\'男\', \'女\', \'保密\']:
sub_menu.add_radiobutton(label=im, command=self.choose_gender, variable=self.genderVar, value=im)
# 建立lang_menu选单,并放入menubar中
lang_menu = Menu(menubar, tearoff=0)
# 新增lang_menu选单
menubar.add_cascade(label=\'选择语言\', menu=lang_menu)
self.langVars = [StringVar(), StringVar(), StringVar(), StringVar()]
# 为lang_menu选单新增选单项
for i, im in enumerate((\'Python\', \'Java\',\'Golang\', \'C++\')):
lang_menu.add_checkbutton(label=im, command=self.choose_lang,
onvalue=im, variable=self.langVars[i])
def choose_gender(self):
messagebox.showinfo(message=(\'选择的性别为: %s\' % self.genderVar.get()))
def choose_lang(self):
rt_list = [e.get() for e in self.langVars]
messagebox.showinfo(message=(\'选择的语言为: %s\' % \',\'.join(rt_list)))
if __name__ == "__main__":
mw = Tk()
mw.title("视窗选单")
mw.geometry(\'200x100\')
mw.iconbitmap(\'image/logo.ico\')
App(mw)
mw.mainloop()
看懂上面的示例,就会基于该示例,建立更复杂的视窗选单
工具条选单
Tkinter没有工具选单元件,通过Frame+Button实现工具条,即Frame为工具条,Button为工具条上的按钮,示例程式码如下:
# -*- coding:utf-8 -*-
from tkinter import *
from tkinter import ttk
from collections import OrderedDict
class App(object):
def __init__(self, mw):
self.mw = mw
self.initWidgets()
def initWidgets(self):
# 初始化图示
self.init_icons()
# 呼叫init_menu初始化选单
self.init_menu()
# 呼叫init_toolbar初始化工具条
self.init_toolbar()
# 建立、新增左边Frame容器
leftframe = ttk.Frame(self.mw, width=40)
leftframe.pack(side=LEFT, fill=Y,expand=True)
# 在左边视窗放一个Listbox
lb = Listbox(leftframe, font=(\'arial\', 20))
lb.pack(fill=Y, expand=YES)
for s in (\'Python\', \'JavaScript\', \'Golang\', \'Java\'):
lb.insert(END, s)
# 建立、新增右边Frame容器
mainframe = ttk.Frame(self.mw)
mainframe.pack(side=LEFT, fill=BOTH, expand=True)
text = Text(mainframe, width=40, font=(\'arial\', 16))
text.pack(side=LEFT, fill=BOTH)
scroll = ttk.Scrollbar(mainframe)
scroll.pack(side=LEFT,fill=Y)
scroll[\'command\'] = text.yview
text.configure(yscrollcommand=scroll.set)
def init_menu(self):
"""初始化选单"""
# 定义3个选单
menus = (\'档案\', \'编辑\', \'帮助\')
# 定义选单资料,(dict,dict,dict...)
items = (OrderedDict([
# 名称,图示,处理函式
(\'新建\', (self.mw.filenew_icon, None)),
(\'开启\', (self.mw.fileopen_icon, None)),
(\'储存\', (self.mw.save_icon, None)),
(\'另存为...\', (self.mw.saveas_icon, None)),
(\'-1\', (None, None)),
(\'退出\', (self.mw.signout_icon, None)),
]),
OrderedDict([(\'撤销\',(None, None)),
(\'重做\',(None, None)),
(\'-1\',(None, None)),
(\'剪下\',(None, None)),
(\'复制\',(None, None)),
(\'贴上\',(None, None)),
(\'删除\',(None, None)),
(\'选择\',(None, None)),
(\'-2\',(None, None)),
# 二级选单
(\'更多\', OrderedDict([
(\'显示资料\',(None, None)),
(\'显示统计\',(None, None)),
(\'显示图表\',(None, None))
]))
]),
OrderedDict([(\'帮助主题\',(None, None)),
(\'-1\',(None, None)),
(\'关于\', (None, None))]))
# 使用Menu建立选单条
menubar = Menu(self.mw)
# 为视窗配置选单条
self.mw[\'menu\'] = menubar
# 遍历menus元组
for i, m_title in enumerate(menus):
# 建立选单
m = Menu(menubar, tearoff=0)
# 新增选单
menubar.add_cascade(label=m_title, menu=m)
# 将当前正在处理的选单资料赋值给tm
tm = items[i]
# 遍历OrderedDict,预设只遍历它的key
for label in tm:
# 二级级选单,如果value是OrderedDict,说明是二级选单
if isinstance(tm[label], OrderedDict):
# 建立子选单、并新增子选单
sm = Menu(m, tearoff=0)
m.add_cascade(label=label, menu=sm)
sub_dict = tm[label]
# 再次遍历子选单对应的OrderedDict,预设只遍历它的key
for sub_label in sub_dict:
if sub_label.startswith(\'-\'):
# 新增分隔条
sm.add_separator()
else:
# 新增选单项
sm.add_command(label=sub_label,image=sub_dict[sub_label][0],
command=sub_dict[sub_label][1], compound=LEFT)
elif label.startswith(\'-\'):
# 一级选单:新增分隔条
m.add_separator()
else:
# 一级选单:新增选单项
m.add_command(label=label,image=tm[label][0],
command=tm[label][1], compound=LEFT)
def init_icons(self):
self.mw.filenew_icon = PhotoImage(file=\'image/filenew.png\')
self.mw.fileopen_icon = PhotoImage(file=\'image/fileopen.png\')
self.mw.save_icon = PhotoImage(file=\'image/filesave.png\')
self.mw.saveas_icon = PhotoImage(file=\'image/saveas.png\')
self.mw.signout_icon = PhotoImage(file=\'image/quit.png\')
# 生成工具条
def init_toolbar(self):
toolframe = Frame(self.mw, height=43, bg=\'lightgray\')
toolframe.pack(fill=X)
frame = ttk.Frame(toolframe)
frame.pack(side=LEFT)
icons = [
self.mw.filenew_icon,
self.mw.fileopen_icon,
self.mw.save_icon,
self.mw.saveas_icon,
self.mw.signout_icon
]
for i, img in enumerate(icons):
ttk.Button(frame, width=20, image=img,
command=None).grid(row=0, column=i, padx=1, pady=1, sticky=E)
if __name__ == "__main__":
mw = Tk()
mw.title("工具条选单")
mw.iconbitmap(\'image/logo.ico\')
App(mw)
mw.mainloop()
右键选单
使用Menu类实现右键选单,需要先建立选单,然后为目标元件的右击事件系结处理函式,当用户单击鼠标右键时,呼叫Menu类例项的post()方法即可在指定位置弹出右键选单
实现右键选单:
# -*- coding:utf-8 -*-
import functools
from tkinter import *
# 汇入ttk
from tkinter import ttk
from collections import OrderedDict
class App(object):
def __init__(self, mw):
self.mw = mw
self.initWidgets()
def initWidgets(self):
self.text = Text(self.mw, height=12, width=60,
foreground=\'darkgray\',
font=(\'arial\', 12),
spacing2=8, # 设定行间距
spacing3=12) # 设定段间距
self.text.pack()
st = \'雷那网, 一个有温度的Python兴趣屋\'
self.text.insert(END, st)
# 为text元件的右键单击事件系结处理函式
self.text.bind(\'\', self.popup)
# 建立Menu物件
self.popup_menu = Menu(self.mw, tearoff = 0)
self.my_items = (OrderedDict([(\'超大\', 16), (\'大\',14), (\'中\',12),(\'小\',10), (\'超小\',8)]),
OrderedDict([(\'红色\',\'red\'), (\'绿色\',\'green\'), (\'蓝色\', \'blue\')]))
for i,k in enumerate([\'字号\',\'颜色\']):
m = Menu(self.popup_menu, tearoff = 0)
# 新增子选单
self.popup_menu.add_cascade(label=k ,menu = m)
# 遍历OrderedDict的key(预设就是遍历key)
for im in self.my_items[i]:
m.add_command(label=im, command=functools.partial(self.choose, x=im))
def popup(self, event):
# 在指定位置显示选单
self.popup_menu.post(event.x_root,event.y_root)
def choose(self, x):
# 如果使用者选择修改字号的子选单项
if x in self.my_items[0].keys():
# 改变字号
self.text[\'font\'] = (\'微软雅黑\', self.my_items[0][x])
# 如果使用者选择修改颜色的子选单项
if x in self.my_items[1].keys():
# 改变颜色
self.text[\'foreground\'] = self.my_items[1][x]
if __name__ == "__main__":
mw = Tk()
mw.title("右键选单")
App(mw)
mw.mainloop()