您的位置:首页 > 编程语言 > Python开发

【请珍藏】python中tkinter窗口菜单的使用(OptionMenu控件和Menu控件),实现完善的记事本

2020-06-01 04:36 162 查看

正在尝试着做一个比较完善的画图软件,计划使用tkinter库中的canvas控件来做, 然后里面有涉及到菜单的使用,因此作为这个画图软件的附带产出物,整理成了本篇博文,分享给大家,一起研究研究,期待能对你工作带来启发和帮助。

不忘初心,方得始终,让我们一起共勉!

好的,言归正传,回归本篇博文的主题:python中tkinter窗口菜单的使用(OptionMenu控件和Menu控件)。

先从宏观上认识一下菜单,其实就是不外乎如下几个内容:

1、菜单的显示位置和绑定的父控件,即该菜单与那个控件绑定,并如何显示。

2、菜单的选项,即该菜单有哪些菜单项。

3、菜单项的事件响应绑定,即每个具体的菜单项与那个事件或者函数进行绑定。

4、按照业务逻辑进行绑定事件或函数的具体实现,每个不同的函数实现各自的业务逻辑,具体实现按需。

那么这里分别介绍两大类的控件,分别是OptionMenu控件和Menu控件。

一、OptionMenu控件

OptionMenu 组件用于构建一个带菜单的按钮,该菜单可以在按钮的四个方向上展开,展开方向可通过 direction 选项控制。 (其中:direction有'below','above','left','right','flush'这几种类型)

master 参数的作用与所有的 Tkinker 组件一样,指定将该组件放入哪个容器中。

variable:指定该按钮上的菜单与哪个变量绑定。

value:指定默认选择菜单中的哪一项。

values:Tkinter 将收集为此参数传入的多个值,为每个值创建一个菜单项。

kwargs:用于为 OptionMenu 配置选项。除前面介绍的常规选项之外,还可通过 direction 选项控制菜单的展开方向。

先初始化主窗口:

[code]from tkinter import*
# 导入ttk
from tkinter import ttk
root =Tk()
root.title("OptionMenu测试")
root.geometry('300x200')
root.mainloop()

然后新建menu并绑定root,相关脚本如下:

[code]sv =StringVar()
om = ttk.OptionMenu(root,
sv,# 绑定变量
'tkinter',# 设置初始选中值
'label',# 以下多个值用于设置菜单项
'text',
'entry',
'listbox',
'treeview',
'notebook',
command = change_option)# 绑定事件处理方法
om.pack(expand=Y)

然后添加响应函数,相关代码如下:

[code]from tkinter import ttk,messagebox
def change_option(val):
print(sv.get(), val)
messagebox.showinfo(message=('你选择了:%s' % val))

最终运行效果如下:

二、Menu控件

Tkinter 为菜单提供了 Menu 类,该类既可代表菜单条,也可代表菜单,还可代表上下文菜单(右键菜单)。简单来说,Menu 类就可以搞定所有菜单相关内容。

程序可调用 Menu 的构造方法来创建菜单,在创建菜单之后可通过如下方法添加菜单项:

add_command():添加菜单项。

add_checkbutton():添加复选框菜单项。

add_radiobutton():添加单选钮菜单项。

add_separator():添加菜单分隔条。

上面的前三个方法都用于添加菜单项,因此都支持如下常用选项:

label:指定菜单项的文本。

command:指定为菜单项绑定的事件处理方法。

image:指定菜单项的图标。

compound:指定在菜单项中图标位于文字的哪个方位。

有了菜单之后,接下来就是如何使用菜单了。

菜单有两种用法:

1.在窗口上方通过菜单条管理菜单。

2.通过鼠标右键触发右键菜单(上下文菜单)。

(一)先实现菜单条管理的菜单。

实现菜单布局:

[code]root =Tk()
root.title("菜单测试")
root.geometry('400x200')
menubar =Menu(root)
root['menu']= menubar
file_menu =Menu(menubar, tearoff=0)
menubar.add_cascade(label='文件', menu=file_menu)
lang_menu =Menu(menubar, tearoff=0)
menubar.add_cascade(label='格式', menu=lang_menu)
file_menu.add_command(label="新建", command = None)
file_menu.add_command(label="打开", command = None)
file_menu.add_command(label="保存", command = None)
file_menu.add_separator()
file_menu.add_command(label="退出", command = None)
lang_menu.add_command(label="字体", command = None)
lang_menu.add_command(label="颜色", command = None)
root.mainloop()

显示如下:

在主窗口增加多行文本框,相关脚本如下:

[code]text =Text(root, height=12, width=60,
foreground='darkgray',
font=('微软雅黑',12),
spacing2=8,# 设置行间距
spacing3=12)# 设置段间距
text.pack(fill=BOTH,expand=Y)
st ='Tkinter 为菜单提供了 Menu 类,该类既可代表菜单条,也可代表菜单,还可代表上下文菜单(右键菜单)。简单来说,Menu 类就可以搞定所有菜单相关内容。\n'
text.insert(END, st)

显示如下:

实现响应函数:

[code]def on_new():
text.delete(1.0,END)

def on_open():
localfile = filedialog.askopenfile(title='打开单个文件',
filetypes=[("文本文件","*.txt")],# 只处理的文件类型
initialdir='D:/')
if(localfile):
text.delete(1.0,END)
with open(localfile.name,'r',encoding='utf-8') as f:
txt = f.readlines()
text.insert(END,txt)
else:
msgbox.showinfo(message=('读取文件异常'))

def on_save():
localfile = filedialog.asksaveasfile(title='保存文件',
filetypes=[("文本文件", "*.txt")],  # 只处理的文件类型
initialdir='D:/')
if(localfile):
txt = text.get(1.0,END)
print(txt)
with open(localfile.name,'w',encoding='utf-8') as f:
f.write(txt)
else:
msgbox.showinfo(message=('读取文件异常'))

def on_exit():
root.destroy()

实现text的滚动条显示:

[code]scroll =Scrollbar(text, command=text.yview)
scroll.pack(side=RIGHT, fill=Y)
# 设置text2的纵向滚动影响scroll滚动条
text.configure(yscrollcommand=scroll.set)
text.configure(state=NORMAL)

运行效果如下:

(二)实现右键菜单

1、实现右键菜单项:

[code]text.bind('<Button-3>', popup)
popup_menu = Menu(text, tearoff=0)
my_items = (OrderedDict([('超大', 16), ('大', 14), ('中', 12),
('小', 10), ('超小', 8)]),
OrderedDict([('红色', 'red'), ('绿色', 'green'), ('蓝色', 'blue')]))
i = 0
for k in ['字体大小', '颜色']:
m = Menu(popup_menu, tearoff=0)
popup_menu.add_cascade(label=k, menu=m)
# 遍历OrderedDict的key(默认就是遍历key)
for im in my_items[i]:
m.add_command(label=im, command=handlerAdaptor(choose, x=im))
i += 1

2、绑定响应函数:

[code]def popup(event):
# 在指定位置显示菜单
popup_menu.post(event.x_root, event.y_root)
def choose(x):
# 如果用户选择修改字体大小的子菜单项
if x in my_items[0].keys():
# 改变字体大小
text['font'] = ('微软雅黑', my_items[0][x])
# 如果用户选择修改颜色的子菜单项
if x in my_items[1].keys():
# 改变颜色
text['foreground'] = my_items[1][x]
def handlerAdaptor(fun, **kwds):
return lambda fun=fun, kwds=kwds: fun(**kwds)

最终实现的效果如下:

好的,感谢关注,最终的一个较为完善的文本文件编辑软件就做好,完全实现了菜单项打开、保存和新建的功能,而且也实现了右键的保存功能,相关完整的代码如下:

[code]from tkinter import *
# 导入ttk
from tkinter import ttk
from tkinter import messagebox as msgbox
from tkinter import filedialog
from collections import OrderedDict

def on_new():
text.delete(1.0,END)

def on_open():
localfile = filedialog.askopenfile(title='打开单个文件',
filetypes=[("文本文件","*.txt")],# 只处理的文件类型
initialdir='D:/')
if(localfile):
text.delete(1.0,END)
with open(localfile.name,'r',encoding='utf-8') as f:
txt = f.readlines()
text.insert(END,txt)
else:
msgbox.showinfo(message=('读取文件异常'))

def on_save():
localfile = filedialog.asksaveasfile(title='保存文件',
filetypes=[("文本文件", "*.txt")],  # 只处理的文件类型
initialdir='D:/')
if(localfile):
txt = text.get(1.0,END)
print(txt)
with open(localfile.name,'w',encoding='utf-8') as f:
f.write(txt)
else:
msgbox.showinfo(message=('读取文件异常'))

def on_exit():
root.destroy()

root =Tk()
root.title("菜单测试")
root.geometry('400x200')

text =Text(root, height=12, width=60,
foreground='darkgray',
font=('微软雅黑',12),
spacing2=8,# 设置行间距
spacing3=12)# 设置段间距
text.pack(fill=BOTH,expand=Y)
st ='Tkinter 为菜单提供了 Menu 类,该类既可代表菜单条,也可代表菜单,还可代表上下文菜单(右键菜单)。简单来说,Menu 类就可以搞定所有菜单相关内容。\n'
text.insert(END, st)
scroll =Scrollbar(text, command=text.yview)
scroll.pack(side=RIGHT, fill=Y)
# 设置text2的纵向滚动影响scroll滚动条
text.configure(yscrollcommand=scroll.set)
text.configure(state=NORMAL)

menubar =Menu(root)
root['menu']= menubar
file_menu =Menu(menubar, tearoff=0)
menubar.add_cascade(label='文件', menu=file_menu)
lang_menu =Menu(menubar, tearoff=0)
menubar.add_cascade(label='格式', menu=lang_menu)
file_menu.add_command(label="新建", command=on_new)
file_menu.add_command(label="打开", command=on_open)
file_menu.add_command(label="保存", command=on_save)
file_menu.add_separator()
file_menu.add_command(label="退出", command=on_exit)
lang_menu.add_command(label="字体", command = None)
lang_menu.add_command(label="颜色", command = None)

def popup(event):
# 在指定位置显示菜单
popup_menu.post(event.x_root, event.y_root)

def choose(x):
# 如果用户选择修改字体大小的子菜单项
if x in my_items[0].keys():
# 改变字体大小
text['font'] = ('微软雅黑', my_items[0][x])
# 如果用户选择修改颜色的子菜单项
if x in my_items[1].keys():
# 改变颜色
text['foreground'] = my_items[1][x]

def handlerAdaptor(fun, **kwds):
return lambda fun=fun, kwds=kwds: fun(**kwds)

text.bind('<Button-3>', popup)
popup_menu = Menu(text, tearoff=0)
my_items = (OrderedDict([('超大', 16), ('大', 14), ('中', 12),
('小', 10), ('超小', 8)]),
OrderedDict([('红色', 'red'), ('绿色', 'green'), ('蓝色', 'blue')]))
i = 0
for k in ['字体大小', '颜色']:
m = Menu(popup_menu, tearoff=0)
popup_menu.add_cascade(label=k, menu=m)
# 遍历OrderedDict的key(默认就是遍历key)
for im in my_items[i]:
m.add_command(label=im, command=handlerAdaptor(choose, x=im))
i += 1

root.mainloop()

欢迎关注我的微信公众号(俊哥随笔),感谢各位的支持!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: