Python [ GUI编程自学 ],虽然但是,还是想出一个系列(完结!!)

        本文主要介绍了GUI编程过程中的菜单:主菜单、上下文菜单

        另外本文还开发了两个具体简单的项目,目的是对之前的学习进行汇总。

        记事本项目:文件的打开、保存、新建、设置背景颜色、快捷键、以及将Python项目打包成exe可执行文件;

        画图项目:简单界面的实现,绘制直线,矩形、画笔、橡皮擦、清屏、颜色框、快捷键... ... 

        可以在我的专栏GUI编程中学习到一些知识,欢迎关注,本期结束!!!撒花!!!

另外本人喜欢赵丽颖!!!所以会放一些图

目录

菜单

23. 主菜单_上下文菜单

24. 记事本项目

打开文件:

保存文件:

新建文件:

设置背景颜色:

快捷键:

完整代码:

Python项目打包成exe可执行文件

25. 画图项目


菜单

23. 主菜单_上下文菜单

GUI程序通常都有菜单,方便用户的交互。我们一般将菜单分为两种:

  1. 主菜单

主菜单通常位于GUI程序上方。

  1. 上下文菜单

通过鼠标右键单击组件而弹出的菜单,一般是和这个组件相关的操作,比如:剪切,复制、粘贴等。

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()  # 事件循环

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值