GUI(Graphics User Interface)图形用户界面编程
1.常用的GUI库
Tkinter
tkinter(Tk interface)是 Python 的标准GUI库,支持跨平台的GUI程序开发。tkinter适合小型的GUI程序编写,也特别适合初学者学习GUI编程。wxPython
wxPython是比较流行的GUI库,适合大型应用程序开发,功能强tkinter,整体设计框架类似于MFC(Microsoft Foundation Classes 微软基础类库)。PyQT
Qt是一种开源的GUI库,适合大型GUI程序开发,PyQT是Qt工具包标准的 Python 实现。我们也可以使用Qt Desginer界面设计器快速开发GUI应用程序
2.tkinter模块:
3.GUI 编程的核心步骤和第一个 GUI 程序
- 创建应用程序主窗口对象(也称根窗口)
通过类Tk的无参构造函数from tkinter import * root = Tk() - 在主窗口中添加各种可视化组件(比如:按钮Button,文本框Lable)
btn01 = Button(root) btn01["text"] = "hello world" - 通过几何布局管理器,管理组件的位置和大小
btn01.pack() - 事件处理
通过绑定事件处理程序,响应用户操作所触发的事件(比如:单击,双击)def hello(e): messagebox.showinfo("Message","hello world") print("你好,世界") btn01.bind("<Button-1>",hello) - 上述整体代码组合示例:
from tkinter import * from tkinter import messagebox root = Tk() btn01 = Button(root) btn01["text"] = "hello world" btn01.pack() def hello(e): # 记得这里一定需要参数 messagebox.showinfo("Message", "hello world") print('你好,世界!') btn01.bind("<Button-1>", hello) root.mainloop()
4.tkinter主窗口
通过 geometry(‘wxh±x±y’)进行设置。w 为宽度,h 为高度。+x 表示距屏幕左边的距离;-x 表示距屏幕右边的距离;+y 表示距屏幕上边的距离;-y 表示距屏幕下边的距离。
5.GUI编程整体描述
-
Tkinter的GUI组件关系图

-
Misc和Wm:
Tkinter的GUI组件有两个根父类,它们都直接继承了 object 类:
Misc:它是所有组件的根父类。
Wm:它主要提供了一些与窗口管理器通信的功能函数。 -
Tk
Misc和Wm派生出子类Tk,它代表应用程序的主窗口。一般应用程序都需要直接或间接使用Tk。 -
Pack、Place、Grid
Pack、Place、Grid是布局管理器。布局管理器管理组件的:大小、位置。通过布局管理器可以将容器中的组件实现合理的排布。 -
BaseWidget
BaseWidget是所有组件的父类 -
Widget
Widget是所有组件类的父类。Widget一共有四个父类:BaseWidget、Pack、Grid、Place。意味着,所有GUI组件同时具备这四个父类的属性和方法。
7.常用组件汇总
| Tkinter类 | 名称 | 简介 |
|---|---|---|
Toplevel | 顶层 | 容器类,可用于为其他组件提供单独的容器;Toplevel 有点类似于窗口 |
Button | 按钮 | 代表按钮组件 |
Canvas | 画布 | 提供绘图功能,包括直线、矩形、椭圆、多边形、位图等 |
Checkbutton | 复选框 | 可供用户勾选的复选框 |
Entry | 单行输入框 | 用户可输入内容 |
Frame | 容器 | 用于装载其它 GUI 组 |
Label | 标签 | 用于显示不可编辑的文本或图标 |
LabelFrame | 容器 | 也是容器组件,类似于 Frame,但它支持添加标题 |
Listbox | 列表框 | 列出多个选项,供用户选择 |
Menu | 菜单 | 菜单组件 |
Menubutton | 菜单按钮 | 用来包含菜单的按钮(包括下拉式、层叠式等) |
OptionMenu | 菜单按钮 | Menubutton 的子类,也代表菜单按钮,可通过按钮打开一个菜单 |
Message | 消息框 | 类似于标签,但可以显示多行文本;后来当 Label 也能显示多行文本之后,该组件基本处于废弃状态 |
PanedWindow | 分区窗口 | 该容器会被划分成多个区域,每添加一个组件占一个区域,用户可通过拖动分隔线来改变各区域的大小 |
Radiobutton | 单选钮 | 可供用户点边的单选钮 |
Scale | 滑动条 | 拖动滑块可设定起始值和结束值,可显示当前位置的精确值 |
Spinbox | 微调选择器 | 用户可通过该组件的向上、向下箭头选择不同的值 |
Scrollbar | 滚动条 | 用于为组件(文本域、画布、列表框、文本框)提供滚动功能 |
Text | 多行文本框 | 显示多行文 |
8.GUI应用程序经典写法
本节程序也是 GUI 应用程序编写的一个主要结构,采用了面向对象的方式,更加合理的组织代码。
通过类 Application 组织整个 GUI 程序,类 Application 继承了 Frame 及通过继承拥有了父类的特性。通过构造函数__init__()初始化窗口中的对象,通过 createWidgets()方法创建窗口中的对象。
Frame 框架是一个 tkinter 组件,表示一个矩形的区域。Frame 一般作为容器使用,可以放置其他组件,从而实现复杂的布局。
"""测试一个经典的面向对象写法的GUI"""
from tkinter import *
from tkinter import messagebox
class Application(Frame):
"""一个经典的GUI程序的写法"""
def __init__(self, master=None): # 将master作为Application的属性,后面传参root,间接调用root将Application与root绑定
super().__init__(master) # super().__init__(master)实际上已经将master作为self的一个属性了 后面传参root将Frame与root绑定
# Frame.__init__(self,master)
self.master = master # 这应该是为了让代码更加方便理解,所以多一步初始化。其实就是可读性,格式的问题,有没有都一样,但官方教程这么写。
self.pack() # Application类的实例化对象其实也是一个组件,所以要调用布局管理器
self.createWidget()
def createWidget(self):
"""创建组件"""
self.btn01 = Button(self) # 在这里Button是一个按钮类,它需要继承我们的Application类来显示,所以传入self指我们实例化出来的Application类
self.btn01['text'] = '点击送花'
self.btn01.pack()
self.btn01['command'] = self.songhua
# 创建一个退出按钮
self.btnQuit = Button(self, text='退出', command=root.destroy) # 证明绑定的master是root,将root换为self.master,\
# 看命令是否成功,测试结果成功,代码解释合理!
self.btnQuit.pack()
def songhua(self):
messagebox.showinfo('送花', '送你一朵花')
if __name__ == '__main__':
root = Tk() # 每一个应用程序都要直接或间接的调用它
root.geometry("400x100+200+300")
root.title("一个经典的GUI测试")
app = Application(master=root)
root.mainloop()

9.Label标签
- 简介:
Label(标签)主要用于显示文本信息,也可以显示图像 - 属性:
Label(标签)有这样一些常见属性:width,height:
用于指定区域大小,如果显示是文本,则以单个英文字符大小为单位(一个S字宽度占2 个字符位置,高度和英文字符一样);如果显示是图像,则以像素为单位。默认值是根据具体显示的内容动态调整。font
指定字体和字体大小,如:font = (font_name,size)image:
显示在Label上的图像,目前tkinter只支持gif格式。fg和bg
fg(foreground):前景色、bg(background):背景色justify
针对多行文字的对齐,可设置justify属性,可选值"left", "center" or "right"
- 代码示例:
# 这里的代码完全是将面向对象的代码框架拿来填补的,所有的不理解请返回去看面向对象的代码框架解释 from tkinter import * class Application(Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.creatWidget() def creatWidget(self): """创建组件""" # 创建不同属性的Label组件 self.label01 = Label(self, height=2, width=10, text='这是一个标签', bg='black', fg='white') # 注意除了self其它属性顺序没有定义,可以从它的源码中看出来,ctrl+点击Label, # 但一般按照内容,大小,颜色来传 self.label02 = Label(self, height=2, width=20, text='这是一个标签', bg='blue', fg='white', font=('黑体', 30)) self.label01.pack() self.label02.pack() # Label显示图片 global photo # 如果不声明为全局变量,调用一次就销毁,而mainloop()一直在循环,需要一直调用 photo = PhotoImage(file='imgs/baidu.gif') self.label03 = Label(self, image=photo,) self.label03.pack() # Label显示多行文本 self.label04 = Label(self, text='人生如洗牌\n我们抽老千', borderwidth=1, relief='solid', justify='right') self.label04.pack() if __name__ == '__main__': root = Tk() root.geometry("800x500+200+300") root.title("Label测试") a = Application(master=root) root.mainloop()
运行结果

10.Options 选项详解
通过学习 Label 组件,我们发现可以通过 Options 设置组件的属性,从而控制组件的各种状态。比如:宽度、高度、颜色、位置等等。我们可以通过三种方式设置 Options 选项,这在各种 GUI 组件中用法都一致。
-
创建对象时,使用可变参数
fred = Button(self, fg="red", bg="blue") -
创建对象后,使用字典索引方式
fred["fg"] = "red"
fred["bg"] = "blue" -
创建对象后,使用
config()方法
fred.config(fg="red", bg="blue") -
如何查看组件的
Options选项:- 可以通过打印
config()方法的返回值,查看 Options 选项
print(fred.config()) - 通过在 IDE 中,点击组件对象的构造方法,进入到方法内观察

- 可以通过打印
-
关于
“standard options 标准选项”和“widget-specific options 组件特定选 项”。我们将常见的选项汇总如下:
| 选项名(别名) | 含义 |
|---|---|
activebackground | 指定组件处于激活状态时的背景色 |
activeforeground | 指定组件处于激活状态时的前景色 |
anchor | 指定组件内的信息(比如文本或图片)在组件中如何显示(当所在组件比信息大时,可以看出效果)。必须为下面的值之一:N、NE、E、SE、S、SW、W、NW 或 CENTER。比如 NW(NorthWest)指定将信息显示在组件左上角 |
bitmap | 指定在组件上显示该选项指定的位图,该选项值可以是 Tk_GetBitmap接收的任何形式的位图。位图的显示方式受 anchor、justify 选项的影响。如果同时指定了 bitmap 和 text,那么 bitmap 覆盖文本;如果同时指定了 bitmap 和 image,那么 image 覆盖 bitmap |
borderwidth | 指定组件正常显示时的 3D 边框的宽度,该值可以是Tk_GetPixels 接收的任何格式 |
cursor | 指定光标在组件上的样式。该值可以是 Tk_GetCursors 接受的任何格式 |
command | 指定按组件关联的命令方法,该方法通常在鼠标离开组件时被触发调用 |
disabledforeground | 指定组件处于禁用状态时的前景色 |
font | 指定组件上显示的文本字体 |
foreground(fg) | 指定组件正常显示时的前景色 |
highlightbackground | 指定组件在高亮状态下的背景色 |
highlightcolor | 指定组件在高亮状态下的前景色 |
highlightthickness | 指定组件在高亮状态下的周围方形区域的宽度,该值可以是Tk_GetPixels 接收的任何格式 |
height | 指定组件的高度,以 font 选项指定的字体的字符高度为单位,至少为1 |
image | 指定组件中显示的图像,如果设置了 image 选项,它将会覆盖 text、bitmap选项 |
justify | 指定组件内部内容的对齐方式,该选项支持 `LEFT(左对齐)、CENTER(居中对齐)或 RIGHT(右对齐)这三个值 |
padx | 指定组件内部在水平方向上两边的空白,该值可以是 Tk_GctPixels 接收的任何格式 |
pady | 指定组件内部在垂直方向上两地的空白,该值可以是 Tk_GctPixels 接收的任何格式 |
relief | 指定组件的 3D 效果,该选项支持的值包括RAISED、SUNKEN、FLAT、RIDGE、SOLID、GROOVE。该值指出组件内部相对于外部的外观样式,比如 RAISED 表示组件内部相对于外部凸起 |
selectbackground | 指定组件在选中状态下的背景色 |
selectborderwidth | 指定组件在选中状态下的 3D 边框的宽度,该值可以是 Tk_GetPixels接收的任何格式 |
selectforeground | 指定组在选中状态下的前景色 |
state | 指定组件的当前状态。该选项支持 NORMAL(正常)、DISABLE(禁用)这两个值 |
takefocus | 指定组件在键盘遍历(Tab 或 Shift+Tab)时是否接收焦点,将该选项设为 1 表示接收焦点;设为 0 表示不接收焦点 |
text | 指定组件上显示的文本,文本显示格式由组件本身、anchor 及justify 选项决定 |
textvariable | 指定一个变量名,GUI 组件负责显示该变量值转换得到的字符串,文本显示格式由组件本身、anchor 及 justify 选项决定 |
underline | 指定为组件文本的第几个字符添加下画线,该选项就相当于为组件绑定了快捷键 |
width | 指定组件的宽度,以 font 选项指定的字体的字符高度为单位,至少为1 |
wraplength | 对于能支持字符换行的组件,该选项指定每行显示的最大字符数,超过该数量的字符将会转到下行显示 |
xscrollcommand | 通常用于将组件的水平滚动改变(包括内容滚动或宽度发生改变)与水平滚动条的 set 方法关联,从而让组件的水平滚动改变传递到水平滚动条 |
yscrollcommand | 通常用于将组件的垂直滚动改变(包括内容滚动或高度发生改变)与垂直滚动条的 set 方法关联,从而让组件的垂直滚动改变传递到垂直滚动条 |
11.Button组件
- 简介:
Button(按钮)用来执行用户的单击操作。Button可以包含文本,也可以包含图像。按钮被单击后会自动调用对应事件绑定的方法 - 代码示例:
from tkinter import * from tkinter import messagebox class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) # 关于这里为什么要加master参数 # 可以在IDE中通过ctrl+单击Frame中查看__init__方法中的参数有master self.master = master self.pack() self.createWidget() def createWidget(self): self.btn01 = Button(self, text="登录", width=5, height=2, anchor=CENTER, command=self.login) self.btn01.pack() global photo photo = PhotoImage(file=r'E:\my_python\2.python深入与提高\GUI编程\imgs\baidu.gif', height=200, width=150) self.btn02 = Button(root, image=photo, command=self.login) self.btn02.pack() self.btn02.config(state="disabled") def login(self): messagebox.showinfo("登录信息", "欢迎登录,hello world") if __name__ == '__main__': root = Tk() root.geometry("200x300+100+300") a = Application(root) root.mainloop()
运行结果

12.Entry单行文本框组件
- 简介:
Entry用来接收一行字符串的控件。如果用户输入的文字长度长于Entry控件的宽度时, 文字会自动向后滚动。如果想输入多行文本, 需要使用Text控件 - 代码示例(一个简单登录框):
from tkinter import * from tkinter import messagebox class Application(Frame): def __init__(self, master): super().__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): self.lab1 = Label(self, text='用户名') self.lab1.pack() # StringVar变量绑定到指定的组件 # StringVar变量的值发生变化,组件内容也变化 # 组件内容发生变化,StringVar变量的值也发生变化 v1 = StringVar() self.eny1 = Entry(self, textvariable=v1) # textvariable显示v1变量设置好的初始值 self.eny1.pack() v1.set("admin") # 给v1变量设置初始值 print(v1.get()) # 通过StringVar变量的get方法获取其设置的值 print(self.eny1.get()) # 通过Entry组件的get方法获取其中输入的值 self.lab2 = Label(self, text='密码') self.lab2.pack() v2 = StringVar() self.eny2 = Entry(self, show='*', textvariable=v2) self.eny2.pack() v2.set(123456) self.btn1 = Button(self, text='登录', command=self.login) self.btn1.pack() # Button(self,text='登录',command=self.login).pack() # 这是按钮创建的另一种方式,优点是代码简洁;缺点是只能使用按钮一次 def login(self): username = self.eny1.get() pwd = self.eny2.get() print("去数据库比对用户名和密码") print("用户名:" + username) print("密码:" + pwd) if username == 'python' and pwd == '654321': messagebox.showinfo(title='show', message='你好,pythonchi!') else: messagebox.showinfo(title='python', message='登录失败,用户名或密码错误!') if __name__ == '__main__': root = Tk() root.geometry("400x130+200+300") app = Application(master=root) root.mainloop()
运行结果

13.Text多行文本框组件
- 简介:
Text(多行文本框)的主要用于显示多行文本,还可以显示网页链接, 图片,HTML页面, 甚至CSS样式表,添加组件等。因此,也常被当做简单的文本处理器、文本编辑器或者网页浏览器来使用。比如IDLE就是Text组件构成的。 - 代码示例
import webbrowser from tkinter import * class Application(Frame): def __init__(self, master): super().__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): self.t1 = Text(self, width=40, height=12, bg='gray') self.t1.pack() self.t1.insert(1.0, "0123456789\nabcdefghij") self.t1.insert(2.3, "越努力,越幸运。最大的公平是不公平,最大的变化是不变化!\n") Button(self, text="重复插入文本", command=self.insertText).pack(side='left') Button(self, text="返回文本", command=self.returnText).pack(side='left') Button(self, text="添加图片", command=self.addImage).pack(side='left') Button(self, text="添加组件", command=self.addWidget).pack(side='left') Button(self, text="通过tag精确控制文本", command=self.textTag).pack(side='left') def insertText(self): # INSERT索引表示在光标处插入 self.t1.insert(INSERT, 'python') # END索引表示在最后插入 self.t1.insert(END, 'python_end') def returnText(self): # Indexes(索引)是用来指向Text组件中文本的位置,Text的组件索引也是对应实际字符之间的位置 # 核心:行号以1开始,列号以0开始 print(self.t1.get(1.2, 1.6)) # 测试Indexes索引返回值 print("所有文本内容:\n" + self.t1.get(1.0, END)) def addImage(self): self.photo = PhotoImage(file="imgs/baidu.gif") self.t1.image_create(END, image=self.photo) def addWidget(self): b1 = Button(self.t1, text='love_python') # Button继承的是self.t1组件 # 在text创建组件的命令 self.t1.window_create(INSERT, window=b1) def textTag(self): self.t1.delete(1.0, END) self.t1.insert(INSERT, '用知识改变现状,命运之轮以动力运转!\n学习python,兴趣促使成功\n百度,百度一下,就能知道!') self.t1.tag_add('python', 2.0, 2.8) # tag_add添加标签name:python可以是任意的名字,就是为了方便设置 self.t1.tag_config('python', background='yellow', foreground='red') self.t1.tag_add('百度', 3.0, 3.2) self.t1.tag_config('百度', underline=True, foreground='red') self.t1.tag_bind('百度', '<Button-1>', self.webshow) def webshow(self, event): webbrowser.open('www.baidu.com') if __name__ == '__main__': root = Tk() root.geometry("400x300+300+200") app = Application(master=root) root.mainloop()
运行结果:

14.Radiobutton 单选按钮
- 简介:
Radiobutton控件用于选择同一组单选按钮中的一个。Radiobutton可以显示文本,也可以显示图像。 - 代码示例:
from tkinter import * from tkinter import messagebox class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): self.v = StringVar() self.v.set("F") self.r1 = Radiobutton(self, text="男性", value="M", variable=self.v) # 继续明确这里的self指的是什么, # 这里的self指的是根窗口也就是root,也可以认为指的是我们的实例化类Application, # 因为我们继承的是root类,Application中的参数中的master就是等于root self.r2 = Radiobutton(self, text="女性", value="F", variable=self.v) self.r1.pack(side="left") self.r2.pack(side="left") Button(self, text="确定", command=self.confirm).pack(side="left") def confirm(self): messagebox.showinfo("测试", "选择的性别:"+self.v.get()) print(self.v.get()) if __name__ == '__main__': root = Tk() a = Application(master=root) root.mainloop()
15.Checkbutton复选按钮
- 简介:
Checkbutton控件用于选择多个按钮的情况。Checkbutton可以显示文本,也可以显示图像 - 代码示例:
from tkinter import * from tkinter import messagebox class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): self.codeHobby = IntVar() self.videoHobby = IntVar() print(self.videoHobby.get()) # 默认值是0 # Checkbutton 未激活的时候默认是0,激活时是1 self.c1 = Checkbutton(self, text="写代码", variable=self.codeHobby, onvalue=1, offvalue=0) self.c2 = Checkbutton(self, text="看视频", variable=self.videoHobby, onvalue=1, offvalue=0) self.c1.pack(side="left") self.c2.pack(side="left") Button(self, text="确定", command=self.confirm).pack(side="left") def confirm(self): if self.videoHobby.get() == 1: messagebox.showinfo("测试", "确定看视频!") if self.codeHobby.get() == 1: messagebox.showinfo("测试", "确定写代码") if __name__ == '__main__': root = Tk() root.geometry("400x50+200+300") app = Application(master=root) root.mainloop()
16.canvas画布
- 简介:
canvas(画布)是一个矩形区域,可以放置图形、图像、组件等。 - 代码示例:
"""测试 Canvas 组件的基本用法,使用面向对象的方式""" import random from tkinter import * class Application(Frame): def __init__(self, master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): self.canvas = Canvas(self, width=300, height=200, bg="green") self.canvas.pack() # 画一条直线 line = self.canvas.create_line(10, 10, 30, 20, 40, 50) # 画一个矩形. rect = self.canvas.create_rectangle(50, 50, 100, 100) # 画一个椭圆.坐标两双。为椭圆的边界矩形左上角和底部右下角 oval = self.canvas.create_oval(50, 50, 100, 100) global photo photo = PhotoImage(file="imgs/baidu.gif", width="100", height="100") self.canvas.create_image(150, 170, image=photo) Button(self, text="画 10 个矩形", command=self.draw50Recg).pack(side="left") def draw50Recg(self): for i in range(0, 10): x1 = random.randrange(int(int(self.canvas["width"]) / 2)) y1 = random.randrange(int(int(self.canvas["height"]) / 2)) x2 = x1 + random.randrange(int(int(self.canvas["width"]) / 2)) y2 = y1 + random.randrange(int(int(self.canvas["height"]) / 2)) self.canvas.create_rectangle(x1, y1, x2, y2) if __name__ == '__main__': root = Tk() root.geometry("400x300+200+300") app = Application(master=root) root.mainloop()
17.布局管理器简介
- 简介:
一个GUI应用程序必然有大量的组件,这些组件如何排布?这时候,就需要使用tkinter提供的布局管理器帮助我们组织、管理在父组件中子组件的布局方式。tkinter提供了三种管理器:pack、grid、place
18.grid布局管理器
-
简介:
grid表格布局,采用表格结构组织组件。子组件的位置由行和列的单元格来确定,并且可以跨行和跨列,从而实现复杂的布局。 -
功能简介:
选项 说明 取值范围 column单元格的列号 从 0 开始的正整数 columnspan跨列,跨越的列数 正整数 row单元格的行号 从 0 开始的正整数 rowspan跨行,跨越的行数 正整数 ipadx,ipady设置子组件之间的间隔, x方向或者y方向,默认单位为像素非负浮点数,默认 0.0padx,pady与之并列的组件之间的间隔, x方向或者y方向,默认单位是像素非负浮点数,默认 0.0sticky组件紧贴所在单元格的某一角,对应于东南西北中以及 4 个角 “ n”, “s”, “w”, “e”, “nw”, “sw”, “se”, “ne”, “center”(默认) -
代码示例:
登录界面设计

from tkinter import * class Application(Frame): def __init__(seljkf, master=None): super(Application, self).__init__(master) self.master = master self.pack() self.createWidget() # row行,column列 def createWidget(self): self.label01 = Label(self, text="用户名") self.label01.grid(row=0, column=0) self.entry01 = Entry(self) self.entry01.grid(row=0, column=1) Label(self, text="用户名为手机号").grid(row=0, column=2) Label(self, text="密码").grid(row=1, column=0) Entry(self, show="*").grid(row=1, column=1) Button(self, text="登录").grid(row=2, column=1, sticky=EW) Button(self, text="取消", command=quit).grid(row=2, column=2, sticky=E) if __name__ == '__main__': root = Tk() root.geometry("400x90+200+300") app = Application(master=None) root.mainloop()通过
grid布局-实现计算器软件界面。根据实际简易计算器的按键分布,设计一个相仿的计算器界面,相应的功能暂不需要实现。

from tkinter import * class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): btnText = [("MC", "M+", "M-", "MR"), ("C", "±", "÷", "×"), (7, 8, 9, "-"), (4, 5, 6, "+"), (1, 2, 3, "="), (0, ".")] Entry(self, width=25).grid(row=0, column=0, columnspan=4, pady=3) # enumerate 循环带前标 for row_index, row in enumerate(btnText): for column_index, column in enumerate(row): if column == 0: Button(self, text=column, width=5)\ .grid(row=row_index+1, column=column_index, columnspan=2, sticky=NSEW) elif column == "=": Button(self, text=column, width=5)\ .grid(row=row_index+1, column=column_index, rowspan=2, sticky=NSEW) elif column == ".": Button(self, text=column, width=5)\ .grid(row=row_index+1, column=column_index+1, sticky=NSEW) else: Button(self, text=column, width=5)\ .grid(row=row_index+1, column=column_index, sticky=NSEW) if __name__ == '__main__': root = Tk() root.geometry("200x220") a = Application(master=root) root.mainloop()
19.pack 布局管理器
-
简介:
pack按照组件的创建顺序将子组件添加到父组件中,按照垂直或者水平的方向自然排布。如果不指定任何选项,默认在父组件中自顶向下垂直添加组件。pack是代码量最少,最简单的一种,可以用于快速生成界面。 -
功能:

-
代码示例:

# coding=utf-8 # 测试 pack 布局管理 from tkinter import * root = Tk() root.geometry("700x220") # Frame 是一个矩形区域,就是用来防止其他子组件 f1 = Frame(root) f1.pack() f2 = Frame(root) f2.pack() btnText = ("流行风", "中国风", "日本风", "重金属", "轻音乐") for txt in btnText: Button(f1, text=txt).pack(side="left", padx="10") for i in range(1, 20): Button(f2, width=5, height=10, bg="black" if i % 2 == 0 else "white").pack(side="left") root.mainloop()
20.place布局管理器
- 简介:
- 功能:


- 代码示例:

from tkinter import * class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) self.master = master self.pack() self.photos = [PhotoImage(file=f"imgs/{i+1}.png") for i in range(7)] print(self.photos) self.pukes = [Label(self.master, image=self.photos[i]) for i in range(7)] # 这里为什么要加self.master,因为Label标签要继承root根窗口,而master传递进来的值就是root根窗口 # 以前在createWidget传递的是self这是因为,createWidget是属于实例方法,self指的是刚刚创建的实例 # 刚刚创建的实例已经调用了初始化方法__init__,已经继承了root根窗口 self.createWidget() def createWidget(self): i = 0 for lab in self.pukes: lab.place(x=10+i*40, y=50) i += 1 self.pukes[0].bind_class("Label", "<Button-1>", self.chupai) def chupai(self, event): # 这里必须传event参数, # 因为你的鼠标键盘操作也相当于一个参数,需要事件参数event来接收 # 具体下一部分会讲到 print(event.widget.winfo_geometry()) print(event.widget.winfo_y()) if event.widget.winfo_y() == 50: event.widget.place(y=30) else: event.widget.place(y=50) if __name__ == '__main__': root = Tk() root.geometry("600x270+200+300") app = Application(master=root) root.mainloop()
21.事件处理
- 简介:
一个 GUI 应用整个生命周期都处在一个消息循环 (event loop) 中。它等待事件的发生,并作出相应的处理。Tkinter提供了用以处理相关事件的机制. 处理函数可被绑定给各个控件的各种事件。widget.bind(event, handler)如果相关事件发生,handler函数会被触发, 事件对象event会传递给hand - 鼠标和键盘事件:
代码 说明 <Button-1><ButtonPress-1><1>鼠标左键按下。 2 表示右键,3 表示中键; <ButtonRelease-1>鼠标左键释放 <B1-Motion>按住鼠标左键移动 <Double-Button-1>双击左键 <Enter>鼠标指针进入某一组件区域 <Leave>鼠标指针离开某一组件区域 <MouseWheel>滚动滚轮; <KeyPress-a>按下 a键,a可用其他键替代<KeyRelease-a>释放 a键。<KeyPress-A>按下 A键(大写的A)<Alt-KeyPress-a>同时按下 alt和a;alt可用ctrl和shift替代<Double-KeyPress-a>快速按两下 a<Control-V>CTRL和V键被同时按下,V可以换成其它键 event对象常用属性名称 说明 char按键字符,仅对键盘事件有效 keycode按键编码,仅对键盘事件有效 keysym按键名称,仅对键盘事件有效。比如按下空格键:键的 char:,键的keycode:32, 键的keysym:space;比如按下a键:键的char:a, 键的keycode:65, 键的keysym:anum鼠标按键,仅对鼠标事件有效 type所触发的事件类型 widget引起事件的组件 width,height组件改变后的大小,仅 Configure有效x,y鼠标当前位置,相对于父容器 x_root,y_root鼠标当前位置,相对于整个屏幕 - 鼠标事件和键盘事件用法测试
from tkinter import * root = Tk() root.geometry("530x300") c1 = Canvas(root, width=200, height=200, bg="green") c1.pack() def mouseTest(event): print("鼠标左键单击位置(相对于父容器):{0},{1}".format(event.x, event.y)) print("鼠标左键单击位置(相对于屏幕):{0},{1}".format(event.x_root, event.y_root)) print("事件绑定的组件:{0}".format(event.widget)) def testDrag(event): c1.create_oval(event.x, event.y, event.x + 1, event.y + 1) def keyboardTest(event): print("键的keycode:{0},键的char:{1},键的keysym:{2}" .format(event.keycode, event.char, event.keysym)) def press_a_test(event): print("press a") def release_a_test(event): print("release a") c1.bind("<Button-1>", mouseTest) c1.bind("<B1-Motion>", testDrag) root.bind("<KeyPress>", keyboardTest) root.bind("<KeyPress-a>", press_a_test) # 只针对小写的a,大写的A不管用 root.bind("<KeyRelease-a>", release_a_test) root.mainloop()
22.lambda表达式详解
- 简介:
lambda表达式定义的是一个匿名函数,只适合简单输入参数,简单计算返回结果,不适合功能复杂情况。lambda定义的匿名函数也有输入、也有输出,只是没有名字。语法格式如下:
lambda 参数值列表:表达式
参数值列表即为输入。
表达式计算的结构即为输出。 - 功能:
lambda 表达式的参数值列表可以为如下内容:lambda 格式 说明 lambda x, y: x*y函数输入是 x和y,输出是它们的积x*ylambda:None函数没有输入参数,输出是 Nonelambda:aaa(3,4)函数没有输入参数,输出是 aaa(3,4)的结果lambda *args: sum(args)输入是任意个数的参数,输出是它们的和 lambda **kwargs: 1输入是任意键值对参数,输出是 1我们在平时使用时,注意 lambda只是一个匿名函数(没有名字的函数),功能不强,不要过度使用 - 代码示例:
使用lambda表达式实现传参from tkinter import * root = Tk() root.geometry("270x50") def mouseTest1(): print("command方式,简单情况:不涉及获取event对象,可以使用") def mouseTest2(a, b): print("a={0},b={1}".format(a, b)) Button(root, text="测试command1", command=mouseTest1).pack(side="left") Button(root, text="测试command2", command=lambda: mouseTest2("hello", "world")).pack(side='left') root.mainloop()
22.多种绑定事件汇总
- 组件对象的绑定
- 通过
command属性绑定(适合简单不需获取event对象)
Button(root,text=”登录”,command=login) - 通过
bind()方法绑定(适合需要获取event对象)
c1 = Canvas();c1.bind(“<Button-1>”,drawLine)
- 通过
- 组件类对象的绑定
- 调用对象的
bind_class函数,将该组件类所有的组件绑定事件:
w.bind_class(“Widget”,”event”,eventhanler)
比如:btn01.bind_class(“Button”,”<Button-1>”,func)
- 调用对象的
- 代码示例:
# coding=utf-8 # 多种事件绑定方式汇总 from tkinter import * root = Tk() root.geometry("270x30") def mouseTest1(event): print("bind()方式绑定,可以获取 event 对象") print(event.widget) def mouseTest2(a, b): print("a={0},b={1}".format(a, b)) print("command 方式绑定,不能直接获取 event 对象") def mouseTest3(event): print("右键单击事件,绑定给所有按钮啦!!") print(event.widget) b1 = Button(root, text="测试 bind()绑定") b1.pack(side="left") # bind 方式绑定事件 b1.bind("<Button-1>", mouseTest1) # command 属性直接绑定事件 b2 = Button(root, text="测试 command2", command=lambda: mouseTest2("hello", "world")) b2.pack(side="left") # 给所有 Button 按钮都绑定右键单击事件<Button-2> b1.bind_class("Button", "<Button-1>", mouseTest3) # Button b1 mouseTest1和mouseTest3均可执行;Button b2 mouseTest3覆盖了mouseTest2,只执行mouseTest3 root.mainloop()
23.OptionMenu 选择项
- 简介:
OptionMenu(选择项)用来做多选一,选中的项在顶部显示。 - 代码示例:
from tkinter import * root = Tk() root.geometry("200x100") v = StringVar(root) v.set("hello world") om = OptionMenu(root, v, "hello python", "hello program", "hello css") om["width"] = 10 om.pack() def test1(): print("你好:", v.get()) Button(root, text="确定", command=test1).pack() root.mainloop()
24.Scale移动滑块
-
简介:
Scale(移动滑块)用于在指定的数值区间,通过滑块的移动来选择值。


-
代码示例:

from tkinter import * root = Tk() root.geometry("400x150") def test1(value): print("滑块的值:", value) newFont = ("宋体", value) a.config(font=newFont) s1 = Scale(root, from_=10, to=50, length=200, tickinterval=5, orient=HORIZONTAL, command=test1) s1.pack() a = Label(root, text="你好,世界", width=10, height=1, bg="green", fg="blue") a.pack() root.mainloop()
25.askcolor颜色选择框
-
简介:
颜色选择框可以帮助我们设置背景色、前景色、画笔颜色、字体颜色等等。 -
代码示例:

from tkinter import * from tkinter.colorchooser import * root = Tk() root.geometry("400x150") def test1(): s1 = askcolor(color="red", title="选择背景色") print(s1) # pass root.config(bg=s1[1]) Button(root, text="选择背景色", command=test1).pack() root.mainloop()
26.askopenfilename文件对话框
-
简介:
文件对话框帮助我们实现可视化的操作目录、操作文件。最后,将文件、目录的信息传入到程序中。文件对话框包含如下一些常用函数:
命名参数options的常见值如下:

-
示例代码:

from tkinter import * from tkinter.filedialog import * root = Tk() root.geometry("400x100") def test1(): # 获取文件绝对路径名 f = askopenfilename(title="上传文件", initialdir="E:/my_python/2.python深入与提高/GUI编程/imgs", filetypes=[("1", ".png")]) # 字典赋值法为Label标签添加文本 show["text"] = f Button(root, text="选择编辑的视频文件", command=test1).pack() show = Label(root, width=60, height=3, bg="white") show.pack() root.mainloop() -
打开txt文件读取内容到窗口

from tkinter import * from tkinter.filedialog import * root = Tk() root.geometry("400x400") def test1(): # 最开始的编码报错信息 <_io.TextIOWrapper name='E:/my_python/测试/test.txt' mode='r' encoding='cp936'> with open(askopenfile(title="上传文件", initialdi="E:/my_python/测试/", filetypes=[("a", ".txt")]).name, "r", encoding="utf-8") as f: show["text"] = f.read() Button(root, text="选择读取的文本文件", command=test1).pack() show = Label(root, width=40, height=10, bg="white") show.pack() root.mainloop()关于其中编码错误的解决方案为:将
with askopenfile(**option) as f重新改写为with open(askopenfile(**option).name,"r",encoding="utf-8") as f即可修改编码,原本错误编码为:# <_io.TextIOWrapper name='E:/my_python/测试/test.txt' mode='r' encoding='cp936'>
27.simpledialog简单输入对话框
simpledialog(简单对话框)包含如下常用函数:函数名 说明 askfloat(title,prompt,**kw)输入并返回浮点数 askinteger(title,prompt,**kw)输入并返回整数 askstring(title,prompt,**kw)输入并返回字符串
参数中,title 表示窗口标题;prompt 是提示信息;命名参数 kw 为各种选项:initialvalue(初始值)、minvalue(最小值)、maxvalue(最大值)。
-
代码示例:

"""简单对话框""" from tkinter.simpledialog import * root = Tk() root.geometry("400x100") def test1(): a = askinteger(title="输入年龄", prompt="请输入年龄", initialvalue=18, minvalue=1, maxvalue=150) # askstring、askfloat 框使用方式一样 show["text"] = a Button(root, text="今年你多大了? 请输入", command=test1).pack() show = Label(root, width=40, height=3, bg="green") show.pack() root.mainloop()
28.通用消息框
-
简介:
messagebox(通用消息框)用于和用户简单的交互,用户点击确定、取消。如下列出了messagebox的常见函数。 -
功能:

-
代码示例:

from tkinter import * from tkinter.messagebox import * root = Tk() root.geometry("400x100") a1 = showinfo(title="测试", message="hello world 你好,世界") print(a1) root.mainloop()
29.ttk子模块控件
- 简介:
我们再前面学的组件是tkinter模块下的组件,整体风格较老较丑。为了弥补这点不足,推出了ttk组件。ttk组件更加美观、功能更加强大。 新增了LabeledScale(带标签的Scale)、Notebook(多文档窗口)、Progressbar(进度条)、Treeview(树)等组件。使用ttk组件与使用普通的Tkinter组件并没有多大的区别,只要导入ttk模块即可。
ttk子模块的官方文档入口
【注】此处我们不展开ttk。如果你的项目确实需要用到复杂的界面,推荐大家使用wxpython或者pyQt。
30.菜单
-
GUI程序通常都有菜单,方便用户的交互。我们一般将菜单分为两种:- 主菜单:通常位于
GUI程序上方。 - 快捷菜单(上下文菜单):通过鼠标右键单击某个组件对象而弹出的菜单,一般是与该组件相关的操作。
- 主菜单:通常位于
-
主菜单
主菜单一般包含:文件、编辑、帮助等,位于GUI窗口的上面。创建主菜单一般有如下4步:- 创建主菜单栏对象
menubar = tk.Menu(root) - 创建菜单,并添加到主菜单栏对象
file_menu = tk.Menu(menubar)
menubar.add_cascade(label=”文件”,menu=file_menu) - 添加菜单项到 2 步中的菜单
file_menu.add_command(label=”打开”)
file_menu.add_command(label=”保存”,accelerator=”^p command=mySaveFile)
file_menu.add_separator()
file_menu.add_command(label=”退出”) - 将主菜单栏添加到根窗口
root[“menu”]=menubar
- 创建主菜单栏对象
-
代码示例:
记事本软件菜单

from tkinter import * from tkinter.filedialog import * from tkinter.colorchooser import * class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) self.master = master self.textpad = None self.pack() self.createWidget() def createWidget(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() def test(self): pass if __name__ == '__main__': root = Tk() root.geometry('450x300+200+300') root.title("my_记事本") app = Application(master=root) root.mainloop() -
上下文菜单
快捷菜单(上下文菜单)是通过鼠标右键单击组件而弹出的菜单,一般是和这个组件相关的操作,比如:剪切、复制、粘贴、属性等。创建快捷菜单步骤如下:- 创建菜单
menubar = tk.Menu(root)
menubar.add_command(label=”字体”) - 绑定鼠标右键单击事件
def test(event): menubar.post(event.x_root,event.y_root) #在鼠标右键单击坐标处显示菜单 root.bind(“<Button-3>”,test) - 创建菜单
-
代码示例:
为记事本程序增加上下文菜单

from tkinter import * from tkinter.colorchooser import * root = Tk() root.geometry("400x400") def openAskColor(): s1 = askcolor(color="red", title="选择背景色") root.config(bg=s1[1]) # 创建快捷菜单 menubar2 = Menu(root) menubar2.add_command(label="颜色", command=openAskColor) # 添加命令型用add_command,添加菜单项用add_cascade menudit = Menu(menubar2, tearoff=0) menudit.add_command(label="剪切") menudit.add_command(label="复制") menudit.add_command(label="粘贴") menubar2.add_cascade(label="编辑", menu=menudit) def test(event): # 菜单在鼠标右键点击的坐标处显示 menubar2.post(event.x_root, event.y_root) # 编辑区 w1 = Text(root, width=50, height=30) w1.pack() w1.bind("<Button-3>", test) root.mainloop()
31.记事本小项目开发
- 结合所学 GUI 知识,开发一款模仿 windows 记事本的软件。包含了基本的功能:
- 新建文本文件
- 保存文件
- 修改文件内容
- 退出
- 各种快捷键处理
- 修改文本区域背
- 记事本源代码
""" 开发一个简单记事本 包含:新建、保存、修改文本内容、退出 包含:各种快捷键的处理 version 1.0 """ from tkinter import * from tkinter.colorchooser import * from tkinter.filedialog import * class Application(Frame): def __init__(self, master=None): super(Application, self).__init__(master) self.master = master self.textpad = None # textpad 表示 Text文本框对象 self.filename = None # filename 表示打开文本文件的名字 self.contextMenu = None # contextMenu 表示上下文菜单对象 self.pack() self.createWidget() def createWidget(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.quit) # 将主菜单添加到根窗口 root["menu"] = menubar # 添加快捷键事件处理 root.bind("<Control-n>", lambda event: self.newfile()) root.bind("<Control-o>", lambda event: self.openfile()) root.bind("<Control-s>", lambda event: self.savefile()) root.bind("<Control-q>", lambda event: 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("<Button-3>", self.createContextMenu) def newfile(self): self.textpad.delete("1.0", "end") # 把Text控件中的内容清空 self.filename = asksaveasfilename(title="另存为", initialfile="未命名.txt", filetypes=[("文本文档", "*.txt")], defaultextension=".txt") print(self.filename) self.savefile() def openfile(self): self.textpad.delete("1.0", "end") # 先把Text控件中的内容清空 with open(askopenfile(title="打开文件").name, "r+", encoding="utf-8") as f: self.textpad.insert(INSERT, f.read()) self.filename = f.name print(f.name) def savefile(self): with open(self.filename, "w") as f: c = self.textpad.get(1.0, END) f.write(c) def exit(self): root.quit() def openAskColor(self): s1 = askcolor(color="red", title="选择背景色") self.textpad.config(bg=s1[1]) def createContextMenu(self, event): # 菜单在鼠标右键单击的坐标除显示 self.contextMenu.post(event.x_root, event.y_root) print(event.x_root, event.y_root) if __name__ == '__main__': root = Tk() root.geometry('450x400+200+300') root.title("my_记事本") app = Application(master=root) root.mainloop() - 实现效果图

32. 画图小项目开发
- 结合所学GUI知识开发一款简单的画图软件,包含如下功能:
- 画笔
- 矩形/椭圆绘制
- 清屏
- 橡皮擦
- 直线/带箭头的直线
- 修改画笔颜色、背景颜色
- 画图小项目源代码
from tkinter import * from tkinter.filedialog import * from tkinter.colorchooser import * # 设置窗口的宽度和高度 win_width = 900 win_height = 450 class Application(Frame): def __init__(self, master=None, bgcolor="white"): super(Application, self).__init__(master) self.master = master self.bgcolor = bgcolor self.x = 0 self.y = 0 self.fgcolor = "white" self.lastDraw = 0 # 表示最后绘制图形的id self.startDrawFlag = False self.pack() self.createWidget() def createWidget(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_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", "<1>", self.eventManager) self.drawpad.bind("<ButtonRelease-1>", self.stopDraw) # 增加颜色切换的快捷键 root.bind("<KeyPress-r>", self.kuaijiejian) root.bind("<KeyPress-g>", self.kuaijiejian) 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 = askcolor(color=self.fgcolor, title="选择画笔颜色") # [(255,0,0),"#ff0000"] self.fgcolor = c[1] def stopDraw(self, event): self.startDrawFlag = False self.lastDraw = 0 def startDraw(self, event): self.drawpad.delete(self.lastDraw) if not self.startDrawFlag: self.startDrawFlag = True self.x = event.x self.y = event.y def myline(self, event): self.startDraw(event) self.lastDraw = \ self.drawpad.create_line(self.x, self.y, event.x, event.y, fill=self.fgcolor) def mylineArrow(self, event): self.startDraw(event) self.lastDraw = \ self.drawpad.create_line(self.x, self.y, event.x, event.y, arrow=LAST, fill=self.fgcolor) def myRect(self, event): self.startDraw(event) self.lastDraw = \ self.drawpad.create_rectangle(self.x, self.y, event.x, event.y, outline=self.fgcolor) def myPen(self, event): self.startDraw(event) 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.startDraw(event) 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("my_画图") app = Application(master=root) root.mainloop() - 画图项目效果图

33.将python程序打包成exe文件
我们可以使用 pyinstaller 模块实现将 python 项目打包成 exe 文件。操作步骤如下:
1. 安装 pyinstaller 模块
在 pycharm 中操作:file-->setting-->Project:xxx -->Project interpretor,再点击+即可。
2. 在 pycharm 的 Terminal 终端输入如下命令:pyinstaller -F xxxx.p
【注】相关参数如下:
--icon=图标路径(pyinstaller -F --icon=my.ico XXXX.py)
-F 打包成一个 exe 文件
-w 使用窗口,无控制台
-c 使用控制台,无窗口
-D 创建一个目录,里面包含 exe 以及其他一些依赖性
本文围绕Python图形用户界面编程展开,介绍了常用GUI库,如Tk interface等。阐述编程核心步骤,包括创建主窗口、添加组件、布局管理和事件处理等。还列举多种组件及用法,如标签、按钮等,并给出记事本和画图小项目开发示例,最后说明程序打包方法。
2054

被折叠的 条评论
为什么被折叠?



