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

正在尝试着做一个比较完善的画图软件,计划使用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 选项控制菜单的展开方向。

先初始化主窗口:

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

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

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

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

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.通过鼠标右键触发右键菜单(上下文菜单)。

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

实现菜单布局:

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()

显示如下:

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

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)

显示如下:

实现响应函数:

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的滚动条显示:

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

运行效果如下:

(二)实现右键菜单

1、实现右键菜单项:

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、绑定响应函数:

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)

最终实现的效果如下:

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

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()

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

发布了15 篇原创文章 · 获赞 16 · 访问量 444

猜你喜欢

转载自blog.csdn.net/dhjabc_1/article/details/105436275
今日推荐