创建菜单时自动出现的“--”及其弹窗处理办法

原始代码:

# 创建菜单项目def create_menu_bar(self):menu_bar = Menu(self)# 添加菜单项目file_menu = Menu(menu_bar)menu_bar.add_cascade(label='文件', menu=file_menu)self['menu'] = menu_bar

弹窗效果如下图:

解决办法:

# 创建菜单项目def create_menu_bar(self):menu_bar = Menu(self)# 添加菜单项目file_menu = Menu(menu_bar, tearoff=0)  # 添加tearoff=0menu_bar.add_cascade(label='文件', menu=file_menu)self['menu'] = menu_bar

解决后效果图:

notpad项目源码(图标需自己添加):

from tkinter import *
from tkinter import filedialog, messagebox
from tkinter.ttk import Scrollbar, Checkbutton, Label, Button
import os
import sysclass NotePad(Tk):icons = ["new_file", "open_file", "save", "cut", "copy", "paste", "undo", "redo", "find_text"]# icons = [0, 1, 2, 3, 4, 5, 6, 7, 8]theme_color = {"Default": "#000000.#FFFFFF","Olive Green": "#D1E7E0.#5B8340","Night Mode": "#FFFFFF.#000000",}icon_res = []N_path = os.path.abspath('.')# 初始化操作def __init__(self):super().__init__()self.file_name = Noneself.set_window()self.create_menu_bar()self.create_tool_bar()self.create_body()self.create_pop_menu()# 设置窗口界面def set_window(self, path=N_path):self.title("01NotePad")max_width, max_height = self.maxsize()align_center = "800x600+%d+%d" % ((max_width - 800) / 2, (max_height - 600) / 2)self.geometry(align_center)self.iconbitmap(path + '\\img\\alipay.png')# 创建菜单项目def create_menu_bar(self):menu_bar = Menu(self)# 添加菜单项目file_menu = Menu(menu_bar, tearoff=0)  # 设置tearoff=0file_menu.add_command(label='新建', accelerator="Crtl+N", command=self.new_file)file_menu.add_command(label='打开', accelerator="Crtl+O", command=self.open_file)file_menu.add_command(label='保存', accelerator="Crtl+S", command=self.save_file)file_menu.add_command(label='另存为', accelerator="Shift+Crtl+S", command=self.save_as)file_menu.add_separator()file_menu.add_command(label='退出', accelerator="Alt+F4", command=self.exit_notpad)menu_bar.add_cascade(label='文件', menu=file_menu)editor_menu = Menu(menu_bar, tearoff=0)editor_menu.add_command(label='撤销', accelerator="Crtl+Z", command=lambda: self.handle_menu_action('撤销'))editor_menu.add_command(label='恢复', accelerator="Crtl+Y", command=lambda: self.handle_menu_action('恢复'))editor_menu.add_separator()  # 分割线editor_menu.add_command(label='剪切', accelerator="Crtl+X", command=lambda: self.handle_menu_action('剪切'))editor_menu.add_command(label='复制', accelerator="Crtl+C", command=lambda: self.handle_menu_action('复制'))editor_menu.add_command(label='粘贴', accelerator="Crtl+V", command=lambda: self.handle_menu_action('粘贴'))editor_menu.add_separator()editor_menu.add_command(label='查找', accelerator="Crtl+F", command=self.find_text_dialog)editor_menu.add_separator()editor_menu.add_command(label='全选', accelerator="Crtl+A", command=self.select_all)menu_bar.add_cascade(label='编辑', menu=editor_menu)view_menu = Menu(menu_bar, tearoff=0)# 显示行号self.is_show_line_num = IntVar()self.is_show_line_num.set(1)  # 设置初始状态:1代表开启功能,0代表关闭,默认开启view_menu.add_checkbutton(label='显示行号', onvalue=1, offvalue=0, variable=self.is_show_line_num,command=self.update_line_num)# 高亮当前行self.is_heighlight_line = IntVar()self.is_heighlight_line.set(1)view_menu.add_checkbutton(label='高亮当前行', onvalue=1, offvalue=0, variable=self.is_heighlight_line,command=self.toggle_highlight)# 主题themes_memu = Menu(menu_bar, tearoff=0)# 后续实现# themes_memu.add_command(label='主题1', command='')# themes_memu.add_command(label='主题2', command='')self.theme_choice = StringVar()self.theme_choice.set("Default")for k in sorted(self.theme_color):themes_memu.add_radiobutton(label=k, variable=self.theme_choice, command=self.change_theme)view_menu.add_cascade(label='主题', menu=themes_memu)menu_bar.add_cascade(label='视图', menu=view_menu)about_menu = Menu(menu_bar, tearoff=0)about_menu.add_command(label='关于', command=lambda: self.show_messagebox("关于"))about_menu.add_command(label='帮助', command=lambda: self.show_messagebox("帮助"))menu_bar.add_cascade(label='关于', menu=about_menu)self['menu'] = menu_bar# 创建工具栏def create_tool_bar(self, path=N_path):tool_bar = Frame(self, height=25, background="#FFFFFF")# 填充X轴tool_bar.pack(fill='x')for icon in self.icons:# tool_icon = PhotoImage(file=r"C:\Users\Trustech\Desktop\01\img\%s.gif" % (icon,))tool_icon = PhotoImage(file=path + "\\img\\%s.png" % (icon,))tool_btn = Button(tool_bar, image=tool_icon, command=self.tool_bar_action(icon)).pack(side="left")# 要将tool_icon添加到icon_resself.icon_res.append(tool_icon)# 界面操作的主体def create_body(self):# 左边行号,中间是文本编辑区,右边是滚动条# 行号区域self.line_number_bar = Text(self, width=4, padx=3, takefocus=0, border=0, background="#F0E68C", state="disable")self.line_number_bar.pack(side='left', fill='y')# 文本编辑区# wrap 如何换行, word表示按照单词自动换行;undo True表示开启撤销功能self.context_text = Text(self, wrap="word", undo=True)# 热键绑定self.context_text.bind("<Control-o>", self.open_file)self.context_text.bind("<Control-O>", self.open_file)self.context_text.bind("<Control-s>", self.save_file)self.context_text.bind("<Control-S>", self.save_file)self.context_text.bind("<Control-n>", self.new_file)self.context_text.bind("<Control-N>", self.new_file)self.context_text.bind("<Any-KeyPress>", lambda e: self.update_line_num())self.context_text.pack(fill='both', expand="yes")# 设置文本输入区self.context_text.tag_config("active_line", background="#EEEEE0")# 滚动条scroll_bar = Scrollbar(self.context_text)scroll_bar['command'] = self.context_text.yviewself.context_text["yscrollcommand"] = scroll_bar.setscroll_bar.pack(side="right", fill="y")# 打开文件def open_file(self, event=None):# 打开文件并进行类型设置input_file = filedialog.askopenfilename(filetypes=[("所有文件", "*.*"), ("文本文档", "*.txt")])if input_file:self.title("{}***01NotePad".format(os.path.basename(input_file)))self.file_name = input_fileself.context_text.delete(1.0, END)with open(input_file, 'r') as _file:self.context_text.insert(1.0, _file.read())# 文件的保存def write_to_file(self, file_name):try:content = self.context_text.get(1.0, END)with open(file_name, 'w') as _file:_file.write(content)self.title("{}---01NotePad".format(os.path.basename(file_name)))except IOError:messagebox.showerror("错误", "文件保存失败!")def save_file(self, event=None):if not self.file_name:self.save_as()else:self.write_to_file(self.file_name)# 新建def new_file(self, event=None):self.title("新建---01NotePad")self.context_text.delete(1.0, END)self.file_name = None# 另存为def save_as(self):input_file = filedialog.askopenfilename(filetypes=[("所有文件", "*.*"), ("文本文档", "*.txt")])if input_file:self.file_name = input_fileself.write_to_file(self.file_name)# 退出def exit_notpad(self):if messagebox.askokcancel("退出", "确定退出吗?"):self.destroy()# 右键菜单【弹出菜单】def create_pop_menu(self):pop_menu = Menu(self.context_text, tearoff=0)for item1, item2 in zip(['剪切', '复制', '粘贴', '撤销', '恢复'], ['cut', 'copy', 'paste', 'undo', 'redo']):pop_menu.add_command(label=item1, compound='left', command=self.tool_bar_action(item2))pop_menu.add_separator()pop_menu.add_command(label='全选', command=self.select_all)# 绑定self.context_text.bind("<Button-3>", lambda event: pop_menu.tk_popup(event.x_root, event.y_root))# 右键菜单的处理def handle_menu_action(self, action_type):if action_type == '撤销':self.context_text.event_generate("<<Undo>>")elif action_type == '恢复':self.context_text.event_generate("<<Redo>>")elif action_type == '剪切':self.context_text.event_generate("<<Cut>>")elif action_type == '复制':self.context_text.event_generate("<<Copy>>")elif action_type == '粘贴':self.context_text.event_generate("<<Paste>>")# 防止事件传递return "break"# 工具栏命令处理def tool_bar_action(self, action_type):def handle():if action_type == 'open_file':self.open_file()elif action_type == 'save':self.save_file()elif action_type == 'new_file':self.new_file()elif action_type == 'cut':self.handle_menu_action("剪切")elif action_type == 'copy':self.handle_menu_action("复制")elif action_type == 'undo':self.handle_menu_action("撤销")elif action_type == 'paste':self.handle_menu_action("粘贴")elif action_type == 'redo':self.handle_menu_action("恢复")# handle返回处理return handle# 全选def select_all(self):self.context_text.tag_add('sel', 1.0, END)return "break"# 行号处理def update_line_num(self):if self.is_show_line_num.get():# 获取所有行row, col = self.context_text.index(END).split('.')# 列举每行的行号line_num_content = "\n".join([str(i) for i in range(1, int(row))])self.line_number_bar.config(state="normal")self.line_number_bar.delete(1.0, END)self.line_number_bar.insert(1.0, line_num_content)self.line_number_bar.config(state="disable")else:self.line_number_bar.config(state="normal")self.line_number_bar.delete(1.0, END)self.line_number_bar.config(state="disable")# 高亮当前行def toggle_highlight(self):if self.is_heighlight_line.get():self.context_text.tag_remove('active_line', 1.0, END)# 设置高亮self.context_text.tag_add("active_line", "insert linestart", "insert lineend+1c")# 通过轮询递归的方式进行处理self.context_text.after(200, self.toggle_highlight)else:self.context_text.tag_remove("active_line", 1.0, END)# 设置查找对话框def find_text_dialog(self):search_dialog = Toplevel(self)search_dialog.title("查找文本")max_width, max_height = self.maxsize()align_center = "340x80+%d+%d" % ((max_width - 340) / 2, (max_height - 80) / 2)search_dialog.geometry(align_center)search_dialog.resizable(False, False)Label(search_dialog, text='查找全部').grid(row=0, column=0, sticky='e')search_text = Entry(search_dialog, width=25)search_text.grid(row=0, column=1, padx=2, pady=2, sticky="we")search_text.focus_set()# 忽略大小写ignore_case_value = IntVar()Checkbutton(search_dialog, text='忽略大小写', variable=ignore_case_value).grid(row=1, column=1, padx=2, pady=2,sticky='e')Button(search_dialog, text='查找',command=lambda: self.search_result(search_text.get(), ignore_case_value.get(), search_dialog,search_text)).grid(row=0, column=2, padx=2, pady=2, sticky="w" + "e")def close_search_dialog():self.context_text.tag_remove('match', 1.0, END)search_dialog.destroy()search_dialog.protocol("WM_DELETE_WINDOW", close_search_dialog)return "break"# 查找的方法def search_result(self, key, ignore_case, search_dialog, search_box):self.context_text.tag_remove('match', 1.0, END)matches_found = 0if key:start_pos = 1.0while True:start_pos = self.context_text.search(key, start_pos, nocase=ignore_case, stopindex=END)if not start_pos:breakend_pos = "{}+{}c".format(start_pos, len(key))self.context_text.tag_add('match', start_pos, end_pos)matches_found += 1start_pos = end_posself.context_text.tag_config('match', foreground='red', background='red')search_box.focus_set()search_dialog.title("发现了%d个匹配的" % matches_found)# 主题切换def change_theme(self):selected_theme = self.theme_choice.get()fg_bg = self.theme_color.get(selected_theme)print(fg_bg)fg_color, bg_color = fg_bg.split('.')self.context_text.config(bg=bg_color, fg=fg_color)# 关于菜单def show_messagebox(self, type):if type == '帮助':messagebox.showinfo("帮助", "这是帮助文档", icon='question')else:messagebox.showinfo("关于", "这是一个简单的记事本程序")if __name__ == '__main__':app = NotePad()app.mainloop()

python学习笔记——tkinter模块相关推荐

  1. Python学习笔记:第三方模块2

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  2. Python学习笔记13_模块

    Python学习笔记13_模块 文章目录 Python学习笔记13_模块 1.导入模块和的方法及使用 2.分层的文件系统中常用的包结构 3.OS 模块 4.sys 模块 5.math 模块 6.ran ...

  3. Python学习笔记:模块

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  4. python学习-->tkinter模块学习之Scale(尺度)学习

    大家好! 今天分享一下关于tkinter中Scale方法的学习例子! 我们今天用Scale帮助我们实现像我们平时页面的滑条一样,拖动的话可以改变显示在标签上的内容! 老规矩,我们先看看我们能够实现什么 ...

  5. python学习-->tkinter模块学习之Listbox(列表框学习)

    大家好! 今天要分享的是学习tkinter模块的Listbox(列表框学习)! 我们今天例子就是通过Listbox帮助我们把对应一条内容放在列表,然后点击按钮在标签显示! 我们先看看代码运行后的结果: ...

  6. Python学习笔记011_模块_标准库_第三方库的安装

    容器 -> 数据的封装 函数 -> 语句的封装 类 -> 方法和属性的封装 模块 -> 模块就是程序 , 保存每个.py文件 # 创建了一个hello.py的文件,它的内容如下 ...

  7. Python学习笔记——glob模块【文件、路径操作】

    最近做了一个将dicom文件转化为mhd文件的任务,由于要进行批量转化所以遍历文件夹必不可少,刚开始学习python编程,所以把用过的模块用法记录下来,以加深记忆,方便查阅,最后参考前人的博客做了gl ...

  8. Python 学习笔记 -- pickle模块,如何腌制泡菜(入门级)

    #关于腌菜的基础操作 #一般情况下学会腌菜的技术可以使文件大小更加小巧,更加持久. #下来是就是一些腌菜的基础用法 import pickle, os #在腌菜之前需要导入腌菜模块#实例一:这是一个保 ...

  9. python学习笔记——hashlib模块

    上篇:https://blog.csdn.net/qq_42489308/article/details/89813895 hashlib Hash,译做"散列",也有直接音译为& ...

最新文章

  1. ipython notebook_50个关于IPython的使用技巧,get起来!
  2. [C++STL]list容器用法介绍
  3. Redis:13--常用功能之redis-cli redis-server等命令
  4. STM32工作笔记0074---UCOSIII 任务管理(中)
  5. 系统封装教程集合电子书
  6. gogoclient java_链路跟踪-GRPC请求 - GoFrame官网 - 类似PHP-Laravel, Java-SpringBoot的Go企业级开发框架...
  7. 【一天一个C++小知识】012.C++11常用新特性汇总
  8. CS224N笔记——反向传播
  9. CC1310在433MHz下的PCB设计指南
  10. matlab二重定积分_matlab 对于变限积分的计算,二重积分 三重积分
  11. ⌈Linux_感受系统美学⌋ 一步一步迈向系统底层 - 寻觅Linux奥秘,探寻Linux下权限管理周边属性
  12. 波士顿房价预测python决策树_模型评价与验证-波士顿房价预测.ipynb
  13. 深度理解CNN中的感受野(大杀器)
  14. 【iMessage苹果相册推日历真机推】改成vue的MVVM模式现在前端趋向是去dom化
  15. arcgis for Android 100.3.0 加载shp数据以及操作
  16. Python selenium 模拟登录QQ空间
  17. Ubuntu红外相机SDK/驱动安装(optris PI 400i / PI 450i)
  18. 开机后黑屏看不到桌面_电脑开机后不显示桌面图标怎么回事 电脑开机后不显示桌面图标解决办法大全!...
  19. 微星GeForce GTX 1050Ti 4G OC
  20. 基于51单片机的电梯控制器设计资料全套。

热门文章

  1. 百度地图API详解之地图标注覆盖物
  2. 多功能智能跟随行李箱控制系统设计 | 本科毕业设计(配套资源及下载链接 汇总整理)
  3. 程序员必修之路---离职与劳动仲裁的纠纷解决
  4. 将百分制成绩转化为5分制成绩。
  5. 看懂了数智化转型的产业链逻辑,也就看懂了用友BIP
  6. HTTP Live Streaming直播源代码软件开发(iOS直播)技术分析与实现
  7. 2021php高级工程师面试题集
  8. ipad-mini 越狱总结
  9. 编写一个 Chrome 浏览器扩展程序
  10. 《灰色と青 (灰色与青) 》歌词(平假名注释)