找回密码
 会员注册
查看: 31|回复: 0

pythonGUI开发tkinter菜单创建,记事本和画图软件综合项目的实战演练

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
67432
发表于 2024-9-4 21:10:56 | 显示全部楼层 |阅读模式
✨✨欢迎大家来到景天科技苑✨✨🎈🎈养成好习惯,先赞后看哦~🎈🎈🏆作者简介:景天科技苑🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:python图形化GUI编程tkinter精讲景天的主页:景天科技苑文章目录菜单1.主菜单1.1【示例】记事本软件的主菜单2.上下文菜单2.1【示例】为记事本程序增加上下文菜单3.【项目】记事本软件开发4.【项目】画图软件开发菜单GUI程序通常都有菜单,方便用户的交互。我们一般将菜单分为两种:主菜单主菜单通常位于GUI程序上方。例如:快捷菜单(上下文菜单)通过鼠标右键单击某个组件对象而弹出的菜单,一般是与该组件相关的操作。1.主菜单主菜单一般包含:文件、编辑、帮助等,位于GUI窗口的上面。创建主菜单一般有如下4步:创建主菜单栏对象menubar=tk.Menu(root)1创建菜单,并添加到主菜单栏对象file_menu=tk.Menu(menubar)menubar.add_cascade(label=”文件”,menu=file_menu)12添加菜单项到2步中的菜单file_menu.add_command(label=”打开”)file_menu.add_command(label=”保存”,accelerator=”^p”command=mySaveFile)file_menu.add_separator()file_menu.add_command(label=”退出”)1234将主菜单栏添加到根窗口root[“menu”]=menubar11.1【示例】记事本软件的主菜单#记事本软件,练习主菜单的设计fromtkinterimport*fromtkinter.filedialogimport*root=Tk();root.geometry("400x400")root.title("记事本")#创建主菜单栏menubar=Menu(root)#创建子菜单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)filename=""defopenfile():globalfilenamew1.delete('1.0','end')#先把Text控件中的内容清空withaskopenfile(title="打开文件")asf:content=f.read()w1.insert(INSERT,content)filename=f.nameprint(f.name)defsavefile():withopen(filename,"w")asf:content=w1.get(1.0,END)f.write(content)defexit():root.quit()#添加菜单项#accelerator快捷键menuFile.add_command(label="打开",accelerator="ctrl+o",command=openfile)menuFile.add_command(label="保存",command=savefile)menuFile.add_separator()#添加分割线menuFile.add_command(label="退出",command=exit)#将主菜单栏加到根窗口root["menu"]=menubarw1=Text(root,width=50,height=30)w1.pack()root.mainloop()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960运行点击文件2.上下文菜单快捷菜单(上下文菜单)是通过鼠标右键单击组件而弹出的菜单,一般是和这个组件相关的操作,比如:剪切、复制、粘贴、属性等。创建快捷菜单步骤如下:创建菜单menubar=tk.Menu(root)menubar.add_command(label=”字体”)12绑定鼠标右键单击事件deftest(event):menubar.post(event.x_root,event.y_root)#在鼠标右键单击坐标处显示菜单root.bind(“”,test)1232.1【示例】为记事本程序增加上下文菜单"""开发记事本软件的菜单"""fromtkinterimport*classApplication(Frame):def__init__(self,master=None):super().__init__(master)#super()代表的是父类的定义,而不是父类对象self.master=masterself.textpad=None#textpad表示Text文本框对象self.pack()self.createWidget()defcreateWidget(self):#创建主菜单栏menubar=Menu(root)#创建子菜单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)#将主菜单栏加到根窗口root["menu"]=menubar#文本编辑区self.textpad=Text(root,width=50,height=30)self.textpad.pack()#创建上下菜单self.contextMenu=Menu(root)self.contextMenu.add_command(label="背景颜色",command=self.test)#为右键绑定事件root.bind("",self.createContextMenu)deftest(self):passdefcreateContextMenu(self,event):#菜单在鼠标右键单击的坐标处显示self.contextMenu.post(event.x_root,event.y_root)if__name__=='__main__':root=Tk()root.geometry("450x300+200+300")root.title("景天科技苑的简易记事本")app=Application(master=root)root.mainloop()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263运行在记事本中,右键可以显示背景颜色3.【项目】记事本软件开发结合所学GUI知识,开发一款模仿windows记事本的软件。包含了基本的功能:新建文本文件保存文件修改文件内容退出各种快捷键处理修改文本区域背景色"""开发记事本软件的菜单"""fromtkinterimport*fromtkinter.filedialogimport*fromtkinter.colorchooserimport*fromtkinterimportmessageboxclassApplication(Frame):def__init__(self,master=None):super().__init__(master)#super()代表的是父类的定义,而不是父类对象self.master=masterself.textpad=None#textpad表示Text文本框对象self.filename=Noneself.pack()self.createWidget()defcreateWidget(self):#创建主菜单栏menubar=Menu(root)#创建子菜单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.exit)#将主菜单栏加到根窗口root["menu"]=menubar#增加快捷键的处理root.bind("",lambdaevent:self.newfile())root.bind("",lambdaevent:self.openfile())root.bind("",lambdaevent:self.savefile())root.bind("",lambdaevent:self.exit())#文本编辑区,多行文本self.textpad=Text(root,width=50,height=30)self.textpad.pack()#创建上下菜单self.contextMenu=Menu(root)self.contextMenu.add_command(label="背景颜色",command=self.openAskColor)#为右键绑定事件root.bind("",self.createContextMenu)defnewfile(self):#如果是第一次新建,就新建新文本,如果是打开程序直接点击保存,就把写进去的内容保存起来ifself.filename:self.textpad.delete("1.0","end")#把text控件中所有的内容清空self.filename=asksaveasfilename(title="另存为",initialfile="未命名.txt",filetypes=[("文本文档","*.txt")],defaultextension=".txt")#判断是否新建,如果未新建,则不用保存ifself.filename:self.savefile()else:self.destroy()else:self.filename=asksaveasfilename(title="另存为",initialfile="未命名.txt",filetypes=[("文本文档","*.txt")],defaultextension=".txt")#判断是否新建,如果未新建,则不用保存ifself.filename:self.savefile()else:self.destroy()defopenfile(self):self.textpad.delete("1.0","end")#把text控件中所有的内容清空#withaskopenfile(title="打开文本文件")asf:别这样用,否则当没有打开文件时,会有个报错f=askopenfile(title="打开文本文件")print("打开的文件对象是:",f)#如果有打开,则在将写入的插入,没打开不用插入,在光标所在处插入文本内容iff:self.textpad.insert(INSERT,f.read())#将打开之后的文件名赋值给self.filenameself.filename=f.nameelse:self.destroy()#实现保存方法defsavefile(self):#第一次打开程序,直接点击保存bug修复print("第一次打开程序点击保存",self.filename)ifself.filename:f=open(self.filename,"w")iff:#获取到文本内容字符串,然后在通过open保存c=self.textpad.get(1.0,END)f.write(c)else:#messagebox.showinfo("Warning","请先新建文件!")self.newfile()defexit(self):root.destroy()defopenAskColor(self):s1=askcolor(color="red",title="选择背景色")self.textpad.config(bg=s1[1])defcreateContextMenu(self,event):#菜单在鼠标右键单击的坐标处显示self.contextMenu.post(event.x_root,event.y_root)if__name__=='__main__':root=Tk()root.geometry("450x300+200+300")root.title("景天的简易记事本")app=Application(master=root)root.mainloop()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127运行点击文件-新建修改文件名点击保存,保存到了桌面点击文件-打开随便写点东西点击文件-保存,查看文件,内容已被保存进去askopenfile返回的文件对象解析,里面的name即为包含路径的文件名字符串修改文本背景色,在文本域右键,背景颜色选一个背景色4.【项目】画图软件开发开发一款简单的画图软件,包含如下功能:画笔矩形/椭圆绘制清屏橡皮擦直线/带箭头的直线修改画笔颜色、背景颜色"""开发画图软件的菜单"""fromtkinterimport*fromtkinter.colorchooserimport*#窗口的宽度和高度win_width=900win_height=450classApplication(Frame):def__init__(self,master=None,bgcolor="#000000"):super().__init__(master)#super()代表的是父类的定义,而不是父类对象self.master=masterself.bgcolor=bgcolorself.x=0self.y=0self.fgcolor="#ff0000"self.lastDraw=0#表示最后绘制的图形的idself.startDrawFlag=Falseself.pack()self.createWidget()defcreateWidget(self):#创建绘图区self.drawpad=Canvas(root,width=win_width,height=win_height*0.9,bg=self.bgcolor)self.drawpad.pack()#创建按钮,并给每个按钮定义一个名字,好区分btn_start=Button(root,text="开始",name="start")btn_start.pack(side="left",padx="10")btn_pen=Button(root,text="画笔",name="pen")btn_pen.pack(side="left",padx="10")btn_rect=Button(root,text="矩形",name="rect")btn_rect.pack(side="left",padx="10")btn_oval=Button(root,text="椭圆",name="oval")btn_oval.pack(side="left",padx="10")btn_clear=Button(root,text="清屏",name="clear")btn_clear.pack(side="left",padx="10")btn_erasor=Button(root,text="橡皮擦",name="erasor")btn_erasor.pack(side="left",padx="10")btn_line=Button(root,text="直线",name="line")btn_line.pack(side="left",padx="10")btn_lineArrow=Button(root,text="箭头直线",name="lineArrow")btn_lineArrow.pack(side="left",padx="10")btn_color=Button(root,text="颜色",name="color")btn_color.pack(side="left",padx="10")#事件处理#按下鼠标左键btn_pen.bind_class("Button","",self.eventManager)#释放按键事件self.drawpad.bind("",self.stopDraw)#增加颜色切换的快捷键root.bind("",self.kuaijiejian)root.bind("",self.kuaijiejian)root.bind("",self.kuaijiejian)defeventManager(self,event):#获取根据名字获取相关按钮name=event.widget.winfo_name()#print("获取widget:",dir(event.widget))print(name)ifname=="line":self.drawpad.bind("",self.myline)elifname=="lineArrow":self.drawpad.bind("",self.mylineArrow)elifname=="rect":self.drawpad.bind("",self.myRect)elifname=="oval":self.drawpad.bind("",self.myOval)elifname=="pen":self.drawpad.bind("",self.myPen)elifname=="erasor":self.drawpad.bind("",self.myErasor)elifname=="clear":#清屏,直接delete("all")self.drawpad.delete("all")elifname=="color":c=askcolor(color=self.fgcolor,title="选择画笔颜色")#[(255,0,0),"#ff0000"]#将选择的颜色赋值给前景色self.fgcolor=c[1]defstopDraw(self,event):self.startDrawFlag=Falseself.lastDraw=0defstartDraw(self,event):self.drawpad.delete(self.lastDraw)ifnotself.startDrawFlag:self.startDrawFlag=Trueself.x=event.xself.y=event.ydefmyline(self,event):self.startDraw(event)#起点在鼠标开始的地方,终点在事件最后发生的地方self.lastDraw=self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor)defmylineArrow(self,event):self.startDraw(event)self.lastDraw=self.drawpad.create_line(self.x,self.y,event.x,event.y,arrow=LAST,fill=self.fgcolor)defmyRect(self,event):self.startDraw(event)#矩形边框颜色outlineself.lastDraw=self.drawpad.create_rectangle(self.x,self.y,event.x,event.y,outline=self.fgcolor)defmyOval(self,event):self.startDraw(event)#椭圆边框颜色outlineself.lastDraw=self.drawpad.create_oval(self.x,self.y,event.x,event.y,outline=self.fgcolor)defmyPen(self,event):#画笔本质上也是直线,只是由无数个小直线组成self.startDraw(event)self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor)#移动画笔,多次重置起始位置,就可以让线跟着鼠标画起来self.x=event.xself.y=event.ydefmyErasor(self,event):self.startDraw(event)#橡皮擦实现的原理是用画布背景的矩形将原图遮盖#将矩形区域放大一些self.drawpad.create_rectangle(event.x-4,event.y-4,event.x+4,event.y+4,fill=self.bgcolor)self.x=event.xself.y=event.ydefkuaijiejian(self,event):ifevent.char=="r":self.fgcolor="#ff0000"elifevent.char=="g":self.fgcolor="#00ff00"elifevent.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()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148运行可以根据各个按钮,实现不同功能
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-3 00:53 , Processed in 0.456095 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表