本文主要介绍了GUI编程过程中的菜单:主菜单、上下文菜单。
另外本文还开发了两个具体简单的项目,目的是对之前的学习进行汇总。
记事本项目:文件的打开、保存、新建、设置背景颜色、快捷键、以及将Python项目打包成exe可执行文件;
画图项目:简单界面的实现,绘制直线,矩形、画笔、橡皮擦、清屏、颜色框、快捷键... ...
可以在我的专栏GUI编程中学习到一些知识,欢迎关注,本期结束!!!撒花!!!
另外本人喜欢赵丽颖!!!所以会放一些图
目录
菜单
23. 主菜单_上下文菜单
GUI程序通常都有菜单,方便用户的交互。我们一般将菜单分为两种:
主菜单
主菜单通常位于GUI程序上方。
上下文菜单
通过鼠标右键单击组件而弹出的菜单,一般是和这个组件相关的操作,比如:剪切,复制、粘贴等。
from tkinter import *
from tkinter.filedialog import *
from tkinter.colorchooser import *
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.textpad = None
self.pack()
self.createWidgets()
def createWidgets(self):
# 创建主菜单栏
menubar = Menu(self.master)
self.master.config(menu=menubar)
# 创建子菜单
menuFile = Menu(menubar)
menuEdit = Menu(menubar)
menuHelp = Menu(menubar)
# 将子菜单加入到主菜单栏
menubar.add_cascade(label='文件(F)', menu=menuFile)
menubar.add_cascade(label='编辑(E)', menu=menuEdit)
menubar.add_cascade(label='帮助(H)', menu=menuHelp)
# 添加菜单项
menuFile.add_command(label='新建', accelerator='Ctrl+n', command=self.test)
menuFile.add_command(label='打开', accelerator='Ctrl+o', command=self.test)
menuFile.add_command(label='保存', accelerator='Ctrl+s', command=self.test)
menuFile.add_separator()
menuFile.add_command(label='退出', accelerator='Ctrl+q', command=self.test)
# 文本编辑区
self.textpad = Text(self.master, width=80, height=30)
self.textpad.pack()
# 创建上下文菜单
self.contextMenu = Menu(self.master, tearoff=0)
self.contextMenu.add_command(label='背景颜色', command=self.test)
# 为文本编辑区绑定右键事件
self.textpad.bind('<Button-3>', self.createContextMenu)
def test(self):
pass
def createContextMenu(self, event):
# 菜单在鼠标右键单击的坐标处显示
try:
self.contextMenu.tk_popup(event.x_root, event.y_root)
finally:
# 可选:确保菜单被隐藏(在某些情况下可能不需要)
self.contextMenu.grab_release()
if __name__ == '__main__':
root = Tk()
root.geometry('450x300+200+300')
root.title('简易笔记本 菜单栏制作')
app = Application(master=root)
root.mainloop()
24. 记事本项目
01 实现了文件的打开、保存、退出功能。
02 实现新建一个文件、背景颜色、实现快捷键
03 Python项目打包成exe可执行文件
打开文件:
def openfile(self):
self.textpad.delete('1.0','end') # 把text控件中所有的内容清空
with askopenfile(title='打开文本文件') as f:
# print(f.read())
self.textpad.insert(INSERT,f.read())
self.filename = f.name
保存文件:
def savefile(self):
with open(self.filename,'w') as f:
c = self.textpad.get(1.0,END)
f.write(c)
新建文件:
def newfile(self):
self.textpad.delete('1.0', 'end') # 把text控件中所有的内容清空
# initialfile:初始化文件名
self.filename = asksaveasfilename(title='另存为',initialfile='未命名.txt',
filetypes=[('文本文档','*.txt')],defaultextension='.txt')
self.savefile()
设置背景颜色:
def openAskColor(self):
s1 = askcolor(color='red',title='选择背景色')
self.textpad.config(bg=s1[1]) #修改文本域
快捷键:
# 增加快捷键的处理
root.bind('<Control-n>',lambda event:self.newfile())
root.bind('<Control-0>', lambda event: self.openfile())
root.bind('<Control-s>', lambda event: self.savefile())
root.bind('<Control-q>', lambda event: self.exitfile())
完整代码:
# 记事本项目01
from tkinter import *
from tkinter.filedialog import *
from tkinter.colorchooser import *
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.textpad = None
self.pack()
self.createWidgets()
def createWidgets(self):
# 创建主菜单栏
menubar = Menu(self.master)
self.master.config(menu=menubar)
# 增加快捷键的处理
root.bind('<Control-n>',lambda event:self.newfile())
root.bind('<Control-0>', lambda event: self.openfile())
root.bind('<Control-s>', lambda event: self.savefile())
root.bind('<Control-q>', lambda event: self.exitfile())
# 创建子菜单
menuFile = Menu(menubar)
menuEdit = Menu(menubar)
menuHelp = Menu(menubar)
# 将子菜单加入到主菜单栏
menubar.add_cascade(label='文件(F)', menu=menuFile)
menubar.add_cascade(label='编辑(E)', menu=menuEdit)
menubar.add_cascade(label='帮助(H)', menu=menuHelp)
# 添加菜单项
menuFile.add_command(label='新建', accelerator='Ctrl+n', command=self.newfile)
menuFile.add_command(label='打开', accelerator='Ctrl+o', command=self.openfile)
menuFile.add_command(label='保存', accelerator='Ctrl+s', command=self.savefile)
menuFile.add_separator() # 添加分割线
menuFile.add_command(label='退出', accelerator='Ctrl+q', command=self.exitfile)
# 文本编辑区
self.textpad = Text(self.master, width=80, height=30)
self.textpad.pack()
# 创建上下文菜单
self.contextMenu = Menu(self.master, tearoff=0)
self.contextMenu.add_command(label='背景颜色', command=self.openAskColor)
# 为文本编辑区绑定右键事件
self.textpad.bind('<Button-3>', self.createContextMenu)
def newfile(self):
self.textpad.delete('1.0', 'end') # 把text控件中所有的内容清空
# initialfile:初始化文件名
self.filename = asksaveasfilename(title='另存为',initialfile='未命名.txt',
filetypes=[('文本文档','*.txt')],defaultextension='.txt')
self.savefile()
def openfile(self):
self.textpad.delete('1.0','end') # 把text控件中所有的内容清空
with askopenfile(title='打开文本文件') as f:
# print(f.read())
self.textpad.insert(INSERT,f.read())
self.filename = f.name
def savefile(self):
with open(self.filename,'w') as f:
c = self.textpad.get(1.0,END)
f.write(c)
def exitfile(self):
root.quit() #退出整个窗口
def openAskColor(self):
s1 = askcolor(color='red',title='选择背景色')
self.textpad.config(bg=s1[1]) #修改文本域
def createContextMenu(self, event):
# 菜单在鼠标右键单击的坐标处显示
try:
self.contextMenu.tk_popup(event.x_root, event.y_root)
finally:
# 可选:确保菜单被隐藏(在某些情况下可能不需要)
self.contextMenu.grab_release()
if __name__ == '__main__':
root = Tk()
root.geometry('450x300+200+300')
root.title('简易笔记本 菜单栏制作')
app = Application(master=root)
root.mainloop()
Python项目打包成exe可执行文件
我们可以使用pyinstaler模块实现将python项目打包成exe 文件。操作步骤如下:
1. 安装 pyinstaller 模块
在 pycharm 中操作:file-->setting-->Project:xxx->Project interpretor,再点击+即可。2. 在 pycharm 的 Terminal 终端输入如下命令:pyinstaller -F xxxx.py
【注】相关参数如下:
--icon=图标路径(pyinstaller -F--icon=my.ico xxXX.py)
-F 打包成一个 exe 文件
-w 使用窗口,无控制台
-c使用控制台,无窗口
-D 创建一个目录,里面包含 exe 以及其他一些依赖性文件
3. 在项目的 dist 目录下可以看到生成了 exe 文件,直接在 windows 系统中使用即可.
出现的问题:
版本问题:pyinstaller的版本下载到最新版支持;
路径问题:必须在本目录下支持,否则会出现py文件不存在的情况。
cd D:\BaiduSyncdisk\BaiduNetdiskDownload\PycharmProjects\MyScripts pyinstaller -F GUI-记事本项目.py
生成目录名称为:dist
25. 画图项目
01 界面实现
02 绘制直线 删除上一个图形
03 箭头直线 矩形绘制
04 画笔和橡皮擦的实现
05 清屏 颜色框 快捷键处理(快捷键处理没有实现...没找出来错误)
from tkinter import *
from tkinter.colorchooser import *
# 窗口的宽度和高度
win_width = 900
win_height = 450
class Application(Frame):
def __init__(self, master=None, bgcolor='#000000'):
super().__init__(master)
self.master = master
self.root = master
self.bgcolor = bgcolor # 背景颜色
self.x = 0
self.y = 0
self.fgcolor = '#ff0000'
self.lastDraw = 0 #表示最后绘制的图形的id
self.startDrawFlag = False
self.pack()
self.createWidgets()
def createWidgets(self):
# 创建绘图区
self.drawpad = Canvas(self, width=win_width, height=win_height*0.9, bg=self.bgcolor)
self.drawpad.pack()
# 创建按钮
self.btn_start = Button(self, text='开始', name='start')
self.btn_start.pack(side='left', padx='10')
self.btn_pen = Button(self, text='画笔', name='pen')
self.btn_pen.pack(side='left', padx='10')
self.btn_rect = Button(self, text='矩形', name='rect')
self.btn_rect.pack(side='left', padx='10')
self.btn_clear = Button(self, text='清屏', name='clear')
self.btn_clear.pack(side='left', padx='10')
self.btn_erasor = Button(self, text='橡皮擦', name='erasor')
self.btn_erasor.pack(side='left', padx='10')
self.btn_line = Button(self, text='直线', name='line')
self.btn_line.pack(side='left', padx='10')
self.btn_lineArrow = Button(self, text='箭头直线', name='lineArrow')
self.btn_lineArrow.pack(side='left', padx='10')
self.btn_color = Button(self, text='颜色', name='color')
self.btn_color.pack(side='left', padx='10')
# 事件处理
self.btn_pen.bind_class('Button','<1>',self.eventManager)
self.drawpad.bind('<ButtonRelease-1>',self.stopDraw)
#增加颜色处理的快捷键
self.root.bind('KeyPress-r',self.kuaijiejian)
self.root.bind('KeyPress-g', self.kuaijiejian)
self.root.bind('KeyPress-y', self.kuaijiejian)
# 事件方法
def eventManager(self,event):
name = event.widget.winfo_name()
print(name)
if name == 'line':
self.drawpad.bind('<B1-Motion>',self.myline) # 绑定鼠标的拖动事件
elif name == 'lineArrow':
self.drawpad.bind('<B1-Motion>',self.mylineArrow)
elif name == 'rect':
self.drawpad.bind('<B1-Motion>',self.myRect)
elif name == 'pen':
self.drawpad.bind('<B1-Motion>',self.myPen)
elif name == 'erasor':
self.drawpad.bind('<B1-Motion>',self.myErasor)
elif name == 'clear':
self.drawpad.delete('all')
elif name == 'color':
# c代表返回的颜色的值
c = askcolor(color=self.fgcolor,title='选择画笔颜色')
# 返回的是一个列表:[(255,0,0),'#fff...']
self.fgcolor = c[1]
# 方法封装
def starDraw(self,event):
self.drawpad.delete(self.lastDraw)
if not self.startDrawFlag:
self.startDrawFlag = True
self.x = event.x
self.y = event.y
def stopDraw(self,event):
self.startDrawFlag = False
self.lastDraw = 0 # 把上次的图形保留下来
# 绑定的方法
# 直线
def myline(self,event):
self.starDraw(event)
# fill = self.fgcolor:直线
self.lastDraw = self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor)
# 箭头直线
def mylineArrow(self,event):
self.starDraw(event)
# arrow = LAST:箭头函数
self.lastDraw = self.drawpad.create_line(self.x,self.y,event.x,event.y,arrow=LAST,fill=self.fgcolor)
# 矩形
def myRect(self, event):
self.starDraw(event)
# outline:矩形
self.lastDraw = self.drawpad.create_rectangle(self.x, self.y, event.x, event.y,outline=self.fgcolor)
# 画笔
def myPen(self,event):
self.starDraw(event)
# 区别:删除了self.lastDraw
self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor)
self.x = event.x
self.y = event.y
# 橡皮擦
def myErasor(self, event):
self.starDraw(event)
# bgcolor:背景色,fg前景色
self.drawpad.create_rectangle(event.x-4, event.y-4, event.x+4, event.y+4, fill=self.bgcolor)
self.x = event.x
self.y = event.y
def kuaijiejian(self,event):
if event.char == 'r':
self.fgcolor = '#ff0000'
elif event.char == 'g':
self.fgcolor = '#00ff00'
elif event.char == 'y':
self.fgcolor = '#ffff00'
if __name__ == '__main__':
root = Tk() # 创建根窗口对象
root.geometry(str(win_width) + 'x' + str(win_height) + '+200+300')
root.title('梦茹画图软件')
app = Application(master=root)
root.mainloop() # 事件循环