Python基于tkinter的GUI编程讲座
图形用户界面(GUI、Graphical User Interface)是基于图形的界面,windows就是一个图形用户界面的操作系统,而DOS是基于字符命令交互的操作系统。图形用户界面由窗口构成,每个窗口都由标题、菜单、控制按钮、滚动条等元素组成。
图形用户界面(GUI)程序也成为桌面(Desktop)程序,是人机交互的图形化的程序。
用Python也可以写出漂亮的桌面程序, Python支持多种图形界面的包(packages)较多,常见的有:
☆ tkinter: tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。它是 Python 自带的 GUI 库(libraries),不需要安装,直接导入 tkinter包(packages)即可使用。在此主要介绍tkinter包(packages)。参见Tk图形用户界面(GUI)在线帮助:Graphical User Interfaces with Tk — Python 3.9.14 documentation
☆ wxPython:wxPython 是一款开源软件,是 Python 语言的一套优秀的 GUI 图形库,允许 Python 程序员很方便的创建完整的、功能键全的 GUI 用户界面。
☆ PyQt:优点界面美观,多个平台,文档和教程丰富。PyQt实现了一个Python模块集。它有超过300类,将近6000个函数和方法。它是一个多平台的工具包,可以运行在所有主要操作系统上,包括UNIX,Windows和Mac。 PyQt采用双许可证,开发人员可以选择GPL和商业许可。在此之前,GPL的版本只能用在Unix上,从PyQt的版本4开始,GPL许可证可用于所有支持的平台。
可将一个窗口看成可被分解的一个空的容器,容器里装了大量的基本组件,通过设置这些基本组件的大小、位置等属性,将空的容器和基本组件组成一个整体的窗口。所以,可将图形界面编程看作是拼图游戏,创建图形用户界面的过程就是完成拼图的过程。
学习 GUI 编程的总体步骤可分为下面三步:
(1)、了解 GUI 包大致包含哪些组件,就相当于熟悉每个积木块到底是些什么东西。
(2)、掌握容器及容器对组件进行布局的方法。
(3)、逐个掌握各组件的用法,则相当于深入掌握每个积木块的功能和用法。
【附注:包(package)、模块(Module)和库(library)
在Python中,简单地说,模块(Module)一般是单个python文件;包(package)由分层模块(Module)构成——相关目录里的模块构成。平时说的Python库(library)既可以是一个模块也可以是一个包,是对模块或包的通俗的说法。
更多情况可见Python的模块(module)和包(package)_软件开发技术爱好者的博客-CSDN博客】
下面介绍使用tkinter来开发GUI编程。
tkinter不需要安装,直接导入 tkinter 即可使用。
tkinter 的 GUI 组件(控件)之间的继承关系参见下图:
Python 的标准编译包含了 tkinter包,这是一个面向对象的接口,指向 Tcl/Tk 组件集(widget set)。
tkinter 的 GUI 组件有两个根父类:1)、Misc:它是所有组件的根父类;2)、Wm:它主要提供了一些与窗口管理器通信的功能函数。
GUI 编程并不需要直接使用它们,但由于它们是所有 GUI 组件的父类,因此 GUI 组件都可以直接使用它们的方法。
Misc 和 Wm 派生了一个子类:Tk,它代表应用程序的主窗口。因此,所有 Tkinter GUI 编程通常都需要直接或间接使用该窗口类。
BaseWidget 是所有组件的基类,它还派生了一个子类:Widget。Widget 代表一个通用的 GUI 组件。Tkinter 所有的 GUI 组件都是Widget 的子类。
Widget 的父类有四个,除 BaseWidget 之外,还有 Pack、Place 和 Grid,这三个父类都是布局管理器,它们负责管理所包含的组件的大小和位置。
图中右边的 Widget 的子类,这些都是 Tkinter GUI 编程的各种 UI 组件。
【附注:函数(function)与方法(method)
本质都是对一段功能代码。
与类和实例无绑定关系的function属于函数(function);
与类和实例有绑定关系的function属于方法(method)。
从它们本质都是对一段功能的抽象来看没啥区别,只不过在类里函数就叫方法,即方法是属于对象的函数,是函数的一种类型。许多资料有时将方法也称为函数,本文亦如此。】
tkinter的组件(小部件、控件、widgets【注】)
【注:tkinte文档中使用的widgets,在许多不同的翻译:组件、小部件、控件,相当于某些开发语言的Components(组件)、controls(控件)】
可以使用tkinter.Tk() 方法生成窗口(窗体),例如(提示:要特别注意其中的大小写,否则出错):
import tkinter
w=tkinter.Tk()
或
import tkinter as tk
w=tk.Tk()
或
from tkinter import *
w= Tk()
窗口(窗体)组件的属性
作用 |
实例 |
|
title |
设置窗口标题 |
window.title(‘xxxxx’) |
geometry |
设置窗口大小,中间不能是*,而是x,加数调整窗口在屏幕上的位置,第1个加数是距离屏幕左边的宽,第2个加数是距离屏幕顶部的高。且有引号 |
window.geometry('600x400+300+200') |
resizable |
设置窗口是否可以变化高(height)、 宽(width),True为可以变化,False为不可变化 |
window.resizable(width=False, height=True) 或 window.resizable(0,1) |
mainloop |
进入消息循环 |
window.mainloop() |
quit |
退出; |
window.quit() |
一个简单的例子、
import tkinter as tk
root = tk.Tk()
root.resizable(0,0)
root.geometry('600x400')
root.geometry('+300+200')
#可以将上两句何为root.geometry('600x400+300+200')
运行之,参见下图:
使用tkinter.Tk生成一个主窗口对象,之后才可以向里面添加组件(文本框、按钮、标签)对象实现GUI开发。
几何管理对象
tkinter 提供三种几何(geometry)管理对象[也叫布局(layout),它提供3种方法:pack、grid 和 place管理同在一个父组件下的所有组件的布局(摆放)。
☆ pack 是按添加顺序排列组件,适用于少量组件的排列,使用较为简单。
☆ grid 是按行/列形式排列组件,grid 把组件(控件)位置作为一个二维表结构来维护, 即按照行列的方式排列组件,组件位置由其所在的行号和列号决定。 行号相同而列号不同的几个组件会被彼此上下排列; 列号相同而行号不同的几个组件会被彼此左右排列。使用 Grid 布局的过程就是为各个组件指定行号和列号的过程. 不需要为每个格子指定大小, Grid 布局会自动设置一个合适的大小。
☆ place 可以指定组件的绝对位置或相对于其他组件的位置,可以指定组件的大小,可以直接根据与父窗口的关系(位置)直接放到想要的位置,可以让组件覆盖到另一个组件上。
pack方法使用语法
WidgetObject.pack(option, …)
其中,WidgetObject代表组件对象,option代表属性
属性参数:
after: |
将组件置于其他组件之后; |
before: |
将组件置于其他组件之前; |
anchor: |
组件的对齐方式,顶对齐'n',底对齐's',左'w',右'e' |
side: |
组件在主窗口的位置,可以为'top','bottom','left','right'(使用时tkinter.TOP,tkinter.LEFT); |
fill: |
填充方式 (Y,垂直,X,水平,BOTH,水平+垂直),是否在某个方向充满窗口 |
expand |
1可扩展,0不可扩展,代表控件是否会随窗口缩放 |
pack布局例子1
简单的将三个 Label 控件 pack 到其父窗口上, 可以使用 fill=X 属性让它们和其父窗口一样宽
from Tkinter import *
root = tk()
root.geometry("350x150") #设置窗体的大小
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack(fill=X)
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(fill=X)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack(fill=X)
运行之,参见下图:
pack布局例子2
上面那几个 Label 从左到右放在一排,可以使用side :
from tkinter import *
root = Tk()
root.geometry("350x150") #设置窗体的大小
w = Label(root, text="red", bg="red", fg="white")
w.pack(padx=5, pady=10, side=LEFT)
w = Label(root, text="green", bg="green", fg="black")
w.pack(padx=5, pady=20, side=LEFT)
w = Label(root, text="blue", bg="blue", fg="white")
w.pack(padx=5, pady=20, side=LEFT)
运行之,参见下图:
grid方法使用语法
WidgetObject.grid(option, …)
其中,WidgetObject代表组件对象,option代表属性
属性参数:
column: |
组件所在的列起始位置; |
columnspan: |
组件的列宽;跨列数 |
row: |
组件所在的行起始位置; |
rowspan: |
组件的行宽;rowspam=3 跨3行 |
sticky |
对齐方式:NSEW(北南东西)上下左右 |
padx、pady |
x方向间距、y方向间距(padx=5) |
例、
from tkinter import *
root = Tk()
root.geometry("350x150") #设置窗体的大小
colours = ['red','green','orange','white','yellow','blue']
r = 0
for c in colours:
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
Entry(bg=c, relief=SUNKEN,width=10).grid(row=r,column=1)
r = r + 1
运行之,参见下图:
place方法
使用语法
WidgetObject.place(option, …)
其中,WidgetObject代表组件对象,option代表属性
属性参数:
anchor: |
组件对齐方式;n, ne, e, se, s, sw, w, nw, or center ; ('n'==N) |
x: |
组件左上角的x坐标; |
y: |
组件左上角的y坐标; |
relx: |
组件左上角相对于窗口的x坐标,应为0-1之间的小数;图形位置相对窗口变化 |
rely: |
组件左上角相对于窗口的y坐标,应为0-1之间的小数; |
width: |
组件的宽度; |
heitht: |
组件的高度; |
relwidth: |
组件相对于窗口的宽度,0-1之间的小数,图形宽度相对窗口变化; |
relheight: |
组件相对于窗口的高度,0-1之间的小数; |
例、
from tkinter import *
root = Tk()
root.geometry("350x150") #设置窗体的大小
lb = Label(root, text='hello Place')
# 使用绝对坐标将Label放置到(0,0)位置上
lb.place(x=0, y=0, anchor=NW)
lb2 = Label(root, text='hello Place')
# 使用相对坐标(0.5,0.5)将Label放置到(0.5*sx,0.5.sy)位置上
lb2.place(relx=0.5, rely=0.5, anchor=CENTER)
运行之,参见下图:
常规组件介绍:
★ Label:标签组件,使用语法:
w = tkinter.Label(parent, option, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
属性简析 |
实例 |
text |
需要在界面显示的Label标签内容 |
Label(root,text=‘xxxxx’) |
height |
组件的高度(所占行数) |
Label(root,text=‘xxxxx’,height=2) |
width |
组件的宽度(所占字符个数) |
Label(root,text=‘xxxxx’,height=2,width=20) |
fg |
前景字体颜色 |
Label(root,text=‘xxxxx’,fg='blue')---显示字体为蓝色 |
bg |
背景颜色 |
Label(root,text=‘xxxxx’,bg=‘red’)---显示背景为红色 |
justify |
多行文本的对齐方式,可选参数为: LEFT、 CENTER、RIGHT,分别是向左、居中、向右对齐 |
Label(root,text=‘xxxxx’,justify=tk.LEFT) |
padx |
文本左右两侧的空格数(默认为1) |
Label(root,text=‘xxxxx’,padx=5) |
pady |
文本上下两侧的空格数(默认为1) |
Label(root,text=‘xxxxx’,pady=5) |
font |
设置字体格式和大小 |
Label(root,text=‘xxxxx’,font=("微软雅黑", 12)) |
photo |
设置背景图片,事先需要指定图片路径 |
photo=tk.PhotoImage(file='指定图片路径') Label(root,text=‘xxxxx’,image=photo) |
compound |
图像背景图位置,可选参数为:botton、top、right、left、center(下、上、右、左、文字覆盖图像) |
photo=tk.PhotoImage(file='指定图片路径') |