目录
【还在学习中。。。】
GUI概念初识
窗体控件:包括窗体、标签、按钮、列表框、滚动条等
事件驱动:单击按钮及释放、鼠标移动、按回车键等
布局管理:Tk有3种布局管理器,分别为Place、Pack、Grid
Widget概览
以下这些都叫Widget,可以翻译为控件、组件或部件,共19个。
在tkinter中所有的Widget其实都是面向对象的类,我们通过调用构造方法来达到创建相关Widget控件的目的。先创建窗口->窗口内创建控件。
1 | 按钮 | Button | 【tkinter、tkinter.ttk】 |
2 | 复选框 | Checkbutton | 【tkinter、tkinter.ttk】 |
3 | 文本框 | Entry | 【tkinter、tkinter.ttk】 |
4 | 框架 | Frame | 【tkinter、tkinter.ttk】 |
5 | 标签 | Label(父对象,options) | 【tkinter、tkinter.ttk】 |
6 | 标签框架 | LabelFrame | 【tkinter、tkinter.ttk】 |
7 | 菜单按钮 | MenuButton | 【tkinter、tkinter.ttk】 |
8 | 单选按钮 | Radiobutton | 【tkinter、tkinter.ttk】 |
9 | 尺度 | Scale | 【tkinter、tkinter.ttk】 |
10 | 滚动条 | Scrollbar | 【tkinter、tkinter.ttk】 |
11 | 面板 | PanedWindow | 【tkinter、tkinter.ttk】 |
12 | 画布 | Canvas | 【tkinter】 |
13 | 列表框 | Listbox | 【tkinter】 |
14 | 菜单 | Menu | 【tkinter】 |
15 | 消息 | Message | 【tkinter】 |
16 | 下拉式菜单 | OptionMenu | 【tkinter】 |
17 | 可微调输入控件 | Spinbox | 【tkinter】 |
18 | 文字区域 | Text | 【tkinter】 |
19 | 上层窗口 | Toplevel | 【tkinter】 |
加强版的tkinter模块
tkinter.ttk,有时简称为ttk,该模块中有17个Widget。
以下11个在tkinter中原本就存在的Widget:
Button、Checkbutton、Entry、Frame、Label、LabelFrame、MenuButton、Radiobutton
Scale、Scrollbar、PanedWindow
以下6个是ttk内新增的Widget:
Combobox | |
Notebook | |
Progressbar进度条 | |
Separator 分隔线 | Separator(父对象,options) |
Sizegrip | |
Treeview |
Widget语法格式
Widget名(父对象,options,...)
第一个参数是父对象,表示这个标签将创建在哪一个父对象内(可想成父窗口或称容器)
Widget有一个共同方法keys()可以用列表传回这个Widget所有的options。
Label的options:
['activebackground', 'activeforeground', 'anchor', 'background', 'bd', 'bg', 'bitmap', 'borderwidth', 'compound', 'cursor', 'disabledforeground', 'fg', 'font', 'foreground', 'height', 'highlightbackground', 'highlightcolor', 'highlightthickness', 'image', 'justify', 'padx', 'pady', 'relief', 'state', 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength']
一、通用的
1.1、Label
下面是Label的一些常用options参数的说明:
1 | anchor | 如果空间大于所需时,控制标签的位置,默认CENTER(居中) |
2 | bg或background | 背景色彩 |
3 | bitmap | 使用默认图标当作标签内容 |
4 | borderwidth或bd | 标签边界宽度,默认1 |
5 | compound | 可以设置标签内含图像和文字时,彼此的位置关系 |
6 | cursor | 当光标在标签上方时的外形 |
7 | fg或foreground | 前景色 |
8 | font | 可选择字形、字形样式与大小 |
9 | height | 标签高度,单位是字符 |
10 | image | 标签以图像方式呈现 |
11 | justify | 存在多行文本时最后一行的对齐方式,取值有LEFT/CENTER/RIGHT(靠左/居中/靠右),默认居中对齐 |
12 | padx/pady | 标签文字与标签区间的间距,单位px |
13 | relief | 控制标签的外框,默认FLAT |
14 | text | 标签内容,如果有"\n”则可输入多行文字 |
15 | textvariable | 可以设置标签以变量方式显示 |
16 | underline | 可以设置第几个文字有下划线,从0开始算,默认-1表示无下划线 |
17 | width | 标签宽度,单位字符 |
18 | wraplength | 文本到多少宽度后换行,单位是字符 |
from tkinter import *
root=Tk()
root.title("ch2_1")
# label=Label(root,text="abcdefghijkllmnopqrstuvwxyz",
# fg='blue',bg='yellow',
# height=3,width=15,
# anchor="s",
# wraplength=80,
# font="Helvetica 20 bold",
# justify="center")
# label=Label(root,bitmap='gray25',compound="left",text="我的天空")
# label=Label(root,text="我的天空",relief="solid")
label=Label(root,text="raised",relief="raised",bg="lightyellow",padx=5,pady=10)
label.pack()
# print(type(label))
PhotoImage (gif图片加载)
from tkinter import *
root=Tk()
root.title("ch2_19")
mgif=PhotoImage(file='1.gif')
# label=Label(root,image=mgif)
label=Label(root,image=mgif,text='mylove',bg='yellow',compound='center',font='Helvetica 40 bold')
label.pack()
root.mainloop()
jpg图片加载
jpg图片的加载需要借助pillow库,注意tkinter中也有Image方法,所以导入的顺序不能错了
from tkinter import *
from PIL import Image,ImageTk
root=Tk()
root.title("ch2_19_2")
# root.geometry("680x400")
image=Image.open('1.jpg')
image2=ImageTk.PhotoImage(image)
text="arjkdkgkdghdgkdkjgkdfjgkjgdlkfjgdfk"
label=Label(root,image=image2,text=text,compound='center',
font='Helvetica 40 bold',justify='left',wraplength=300)
label.pack()
root.mainloop()
config方法-计时器
from tkinter import *
counter=0
def run_counter(digit):
def counting():
global counter
counter+=1
digit.config(text=str(counter))
digit.after(1000,counting)
counting()
root=Tk()
root.title("ch2_23")
digit=Label(root,bg='yellow',fg='blue',height=3,width=10,
font='Helvetic 20 bold')
digit.pack()
run_counter(digit)
root.mainloop()
这段代码使用了Python中的闭包(closure)和装饰器(decorator)的概念,以及Tkinter库中的GUI组件更新机制。
def run_counter(digit)
: 这是一个函数定义,它接受一个参数digit
,这个参数是一个Tkinter的Label或其他可以显示文本的GUI组件。
def counting()
: 这是一个嵌套函数(nested function),它定义在run_counter
函数内部。这个函数的作用是每秒钟更新一次全局变量counter
的值,并将更新后的值显示在digit
这个GUI组件上。
digit.config(text=str(counter))
: 这行代码更新digit
这个GUI组件的文本内容,将其设置为当前counter
的值。
digit.after(1000, counting)
: 这行代码使用Tkinter的after
方法,它会在1000毫秒(即1秒)后调用counting
函数,从而实现每秒钟更新一次计数器的效果。总结来说,这是一种使用闭包和装饰器模式来创建一个定时更新GUI组件的计数器的写法。闭包允许内部函数
counting
访问外部函数run_counter
的参数digit
,而装饰器模式则允许counting
函数在每次调用后自动安排下一次调用,从而实现定时更新。
label.grid()方法布局
from tkinter import *
root=Tk()
root.title("ch4_10")
label=Label(root,text="",bg="yellow",width=20)
btn1=Button(root,text="7",width=3)
btn2=Button(root,text="8",width=3)
btn3=Button(root,text="9",width=3)
btn4=Button(root,text="*",width=3)
btn5=Button(root,text="4",width=3)
btn6=Button(root,text="5",width=3)
btn7=Button(root,text="6",width=3)
btn8=Button(root,text="-",width=3)
btn9=Button(root,text="1",width=3)
btn10=Button(root,text="2",width=3)
btn11=Button(root,text="3",width=3)
btn12=Button(root,text="+",width=3)
btn13=Button(root,text="0",width=8)
btn14=Button(root,text=".",width=3)
btn15=Button(root,text="=",width=3)
label.grid(row=0,column=0,columnspan=4,pady=5)
btn1.grid(row=1,column=0,columnspan=1,padx=5)
btn2.grid(row=1,column=1,columnspan=1,padx=5)
btn3.grid(row=1,column=2,columnspan=1,padx=5)
btn4.grid(row=1,column=3,columnspan=1,padx=5)
btn5.grid(row=2,column=0,columnspan=1,padx=5)
btn6.grid(row=2,column=1,columnspan=1,padx=5)
btn7.grid(row=2,column=2,columnspan=1,padx=5)
btn8.grid(row=2,column=3,columnspan=1,padx=5)
btn9.grid(row=3,column=0,columnspan=1,padx=5)
btn10.grid(row=3,column=1,columnspan=1,padx=5)
btn11.grid(row=3,column=2,columnspan=1,padx=5)
btn12.grid(row=3,column=3,columnspan=1,padx=5)
btn13.grid(row=4,column=0,columnspan=2,padx=5)
btn14.grid(row=4,column=2,columnspan=1,padx=5)
btn15.grid(row=4,column=3,columnspan=1,padx=5)
root.mainloop()
1.2、PanedWindow
from tkinter import *
pw=PanedWindow(orient=VERTICAL)
pw.pack(fill=BOTH,expand=True)
top=Label(pw,text="Top Pane")
pw.add(top)
buttom=Label(pw,text="Bottom Pane")
pw.add(buttom)
pw.mainloop()
1.3、LabelFrame
from tkinter import *
from tkinter.ttk import *
root=Tk()
root.title("ch14_3")
pw=PanedWindow(orient=HORIZONTAL)
leftFrame=LabelFrame(pw,text="Left Pane",width=120,height=150)
pw.add(leftFrame,weight=2)
middleFrame=LabelFrame(pw,text="Middle Pane",width=120)
pw.add(middleFrame,weight=2)
rightFrame=LabelFrame(pw,text="Right Pane",width=120)
pw.add(rightFrame,weight=1)
pw.pack(fill=BOTH,expand=True,padx=10,pady=10)
root.mainloop()
二、tkinter专有
2.1、Menu菜单复选框
from tkinter import *
def status():
if demoStatus.get():
statusLabel.pack(side=BOTTOM, fill=X)
else:
statusLabel.pack_forget()
root = Tk()
root.title("ch16_10")
root.geometry("300x180")
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=False)
menubar.add_cascade(label='File', menu=filemenu)
filemenu.add_command(label='Exit!', command=root.destroy)
viewmenu = Menu(menubar, tearoff=False)
menubar.add_cascade(label='View', menu=viewmenu)
demoStatus = BooleanVar()
demoStatus.set(True)
viewmenu.add_checkbutton(label='View', command=status, variable=demoStatus)
root.config(menu=menubar)
# statusVar = StringVar()
# statusVar.set("显示")
# statusLabel = Label(root, textvariable=statusVar, relief='raised')
# statusLabel.pack(side=BOTTOM, fill=X)
statusLabel = Label(root, text="显示", relief='raised')
statusLabel.pack(side=BOTTOM, fill=X)
root.mainloop()
2.2、工具栏
from tkinter import *
root=Tk()
root.title("ch16_11")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar,tearoff=False)
menubar.add_cascade(label='File',menu=filemenu)
filemenu.add_command(label='Exit!',command=root.destroy)
toolbar=Frame(root,relief=RAISED,borderwidth=3)
mygif=PhotoImage(file='2.gif')
exitBtn=Button(toolbar,image=mygif,command=root.destroy)
exitBtn.pack(side=LEFT,pady=3,padx=3)
toolbar.pack(side=TOP,fill=X)
root.config(menu=menubar)
root.mainloop()
三、tkinter.ttk专有
3.1、Separator分隔线
from tkinter import *
from tkinter.ttk import Separator
root=Tk()
root.title("ch2_26")
myTitle="一个人的几经履行"
myContent="""2016年12月,我一个人订了机票和船票,
开始我的南极旅行,飞机经独白再往阿根廷的乌斯怀亚,
再次我登上的邮轮开始我的南极之旅"""
lab1=Label(root,text=myTitle,font="Helvetic 20 bold")
lab1.pack()
sep=Separator(root,orient=HORIZONTAL)
sep.pack(fill=X,padx=5)
lab2=Label(root,text=myContent)
lab2.pack(padx=10,pady=10)
root.mainloop()
pack的部分参数
fill=x | 填满x轴 |
padx=10 | 与窗口边界左右均相差10px |
pady=10 | 与窗口边界上下均相差10px |
3.2、notebook
from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
def msg():
messagebox.showinfo("Help", "欢迎使用帮助")
root = Tk()
root.title("ch14_7")
root.geometry("300x160")
notebook = Notebook(root)
notebook.pack(fill=BOTH, expand=True)
frame1 = Frame()
frame2 = Frame()
notebook.add(frame1, text="选项卡1")
notebook.add(frame2, text="选项卡2")
label = Label(frame1, text="Python")
label.pack(pady=10)
btn = Button(frame2, text="Help", command=msg)
btn.pack(pady=10)
root.mainloop()
3.3、Progressbar进度条
from tkinter import *
from tkinter.ttk import *
def load():
pb["value"] = 0
pb["maximum"] = maxbytes
loading()
def loading():
global bytes
bytes += 500 # 模拟每次下载500B
pb["value"] = bytes # 设置指针
if bytes < maxbytes:
pb.after(50, loading) # 经过0.05s继续执行loading
root = Tk()
root.title("ch15_3")
root.geometry("300x180")
bytes = 0 # 设置初值
maxbytes = 10000 # 架设下载文件大小
pb = Progressbar(root, length=200)
pb.pack(pady=10, padx=10)
pb["value"] = 0 # 初始值
btn = Button(root, text="Load", command=load)
btn.pack(pady=10)
root.mainloop()
3.4、Combobox
3.5、Sizegrip
3.6、Treeview
学习书籍:《Python GUI设计tkinter菜鸟编程(增强版) 洪锦魁 主编 2024-02-01》