Tkinter
转自:https://morvanzhou.github.io/tutorials/python-basic/tkinter/2-01-label-button/
什么是Tkinter?
Tkinter 是使用 python 进行窗口视窗设计的模块. 简单的构造, 多平台, 多系统的兼容性, 能让它成为让你快速入门定制窗口文件的好助手. 它在 python 窗口视窗模块中是一款简单型的. 所以用来入门, 熟悉 窗口视窗的使用, 非常有必要.。
Label & Button 标签和按钮
窗口主体框架
每一个 tkinter 应用的主体框架都可以包含下面这部分. 定义 window
窗口 和 window
的一些属性, 然后书写窗口内容, 最后执行window.mainloop
让窗口活起来.
import tkinter as tk window = tk.Tk() window.title('my window')
##窗口尺寸
window.geometry('200x100')
# 这里是窗口的内容
##显示出来
window.mainloop()
窗口内容
这次我们会建立一个用来描述的标签 tk.Label
, 比如:
l = tk.Label(window, text='OMG! this is TK!', # 标签的文字 bg='green', # 背景颜色 font=('Arial', 12), # 字体和字体大小 width=15, height=2 # 标签长宽 ) l.pack() # 固定窗口位置
我们也可以通过变量的形式控制标签的显示, 这时我们引入按钮 tk.Button
的概念, 没点一次按钮, 标签变化一次. 用一下内容替换上面的标签. 并把需要变化的文字存成变量 var
:
var = tk.StringVar() # 这时文字变量储存器 l = tk.Label(window, textvariable=var, # 使用 textvariable 替换 text, 因为这个可以变化 bg='green', font=('Arial', 12), width=15, height=2) l.pack()
接着我们来做 按钮 tk.Button
:
b = tk.Button(window, text='hit me', # 显示在按钮上的文字 width=15, height=2, command=hit_me) # 点击按钮式执行的命令 b.pack() # 按钮位置
那么点击是的命令我们用 if
else
语句来判断. 用 on_hit
来判断当前状态.
on_hit = False # 默认初始状态为 False def hit_me(): global on_hit if on_hit == False: # 从 False 状态变成 True 状态 on_hit = True var.set('you hit me') # 设置标签的文字为 'you hit me' else: # 从 True 状态变成 False 状态 on_hit = False var.set('') # 设置 文字为空
没有点击时:
点击第一次:
点击第二次:
Entry & Text 输入, 文本框
窗口内容(窗口上的控件)
创建按钮分别触发两种情况
b1 = tk.Button(window,text="insert point",width=15,height=2,command=insert_point) b1.pack() b2 = tk.Button(window,text="insert end",command=insert_end) b2.pack()
创建输入框entry,用户输入任何内容都显示为*
e = tk.Entry(window,show='*') e.pack()
创建一个文本框用于显示
t = tk.Text(window,height=2)
t.pack()
定义触发事件时的函数(注意:因为Python的执行顺序是从上往下,所以函数一定要放在按钮的上面)
def insert_point(): var = e.get() t.insert('insert',var) def insert_end(): var = e.get() t.insert('end',var)
窗口界面
Listbox 列表部件
创建一个label用于显示
var1 = tk.StringVar() #创建变量 l =tk.Label(window,bg='yellow',width=4,textvariable=var1) l.pack()
创建一个方法用于按钮的点击事件
def print_selection(): value = lb.get(lb.curselection()) #获取当前选中的文本 var1.set(value) #为label设置值
创建一个按钮
b1 = tk.Button(window, text='print selection', width=15, height=2, command=print_selection) b1.pack()
创建一个Listbox和变量var2,并将var2的值赋给Listbox
var2 = tk.StringVar() var2.set((11,22,33,44)) #为变量设置值 #创建Listbox lb = tk.Listbox(window, listvariable=var2) #将var2的值赋给Listbox #创建一个list并将值循环添加到Listbox控件中 list_items = [1,2,3,4] for item in list_items: lb.insert('end', item) #从最后一个位置开始加入值 lb.insert(1, 'first') #在第一个位置加入'first'字符 lb.insert(2, 'second') #在第二个位置加入'second'字符 lb.delete(2) #删除第二个位置的字符 lb.pack() #显示主窗口 window.mainloop()
Radiobutton 选择按钮
radiobutton 部件
首先我们需要定义一个 var
用来将 radiobutton 的值和 Label 的值联系在一起. 然后创建一个radiobutton部分:
var = tk.StringVar() l = tk.Label(window, bg='yellow', width=20, text='empty') l.pack() r1 = tk.Radiobutton(window, text='Option A', variable=var, value='A', command=print_selection) r1.pack()
其中variable=var
, value='A'
的意思就是,当我们鼠标选中了其中一个选项,把value的值A
放到变量var中,然后赋值给variable
触发功能
我们将定义一个功能, 用来对选择的 radiobutton 进行操作. print_selection
功能就是选择了某个 radiobutton 后我们会在屏幕上打印的选项.
def print_selection(): l.config(text='you have selected ' + var.get())
当触发这个函数功能时,我们的 label
中就会显示 text
所赋值的字符串即 ‘you have selected’, 后面则是我们所选中的选项 var.get()
就是获取到变量 var
的值, 举个例子就是我们一开始所做的将选项 “option A” 选中时的值以 “A” 放入 var
中, 所以获取的也就是A 即如果我们这时候选中 “option A” 选项,label显示的值则是 “you have selected A”.
再补充一下 Tkinter 的必备步骤, 整个框架的全部代码就完美了.
这一次的效果将会像下面的图片一样.
Scale 尺度
scale 部件
s = tk.Scale(window, label='try me', from_=5, to=11, orient=tk.HORIZONTAL, length=200, showvalue=0, tickinterval=2, resolution=0.01, command=print_selection) s.pack()
这里的参数label
是指scale部件的名称,即在这里scale部件名称为try me
- 参数
from_=5,to=11
的意思就是从5到11,即这个滚动条最小值为5,最大值为11(这里使用from_是因为在python中有from这个关键词) - 参数
orient=tk.HORIZONTAL
在这里就是设置滚动条的方向,如我们所看到的效果图,这里HORIZONTAL
就是横向。 - 参数
length
这里是指滚动条部件的长度,但注意的是和其他部件width表示不同,width表示的是以字符为单位,比如width=4
,就是4个字符的长度,而此处的length=200
,是指我们常用的像素为单位,即长度为200个像素 - 参数
resolution=0.01
这里我们可以借助数学题来理解,我们做的很多数学题都会让我们来保留几位小数,此处的0.01就是保留2位小数,即效果图中的5.00 9.00等等后面的两位小数,如果保留一位就是resolution=0.1
这里的showvalue
就是设置在滚动条上方的显示。showvalue=0
显示的就是效果图,上方无结果显示,如果改为showvalue=1
,则会显示为:
参数tickinterval
设置的就是坐标的间隔,此处为tickinterval=2
,显示的即为效果图中的5.00 7.00 9.00 11.00 如果改为tickinterval=3
则为5.00 8.00 11.00:
触发功能
l = tk.Label(window, bg='yellow', width=20, text='empty') l.pack() def print_selection(v): l.config(text='you have selected ' + v)
这里相比前面多了参数v
,这里的参数v
即将滚动条定位的数据,即如效果图中最开始,定位到5.00,label
中显示you have selected 5.00
Checkbutton 勾选项
Checkbutton部件
var1 = tk.IntVar() c1 = tk.Checkbutton(window, text='Python', variable=var1, onvalue=1, offvalue=0, command=print_selection) c1.pack()
参数onvalue
和前面讲的部件radiobutton
中的value相似, 当我们选中了这个checkbutton,onvalue
的值1就会放入到var1
中, 然后var1将其赋值给参数variable
,offvalue
用法相似,但是offvalue
是在没有选中这个checkbutton时,offvalue
的值1放入var1,然后赋值给参数variable
这是创建一个checkbutton部件,以此类推,可以创建多个checkbutton
触发功能
def print_selection(): if (var1.get() == 1) & (var2.get() == 0): #如果选中第一个选项,未选中第二个选项 l.config(text='I love only Python ') elif (var1.get() == 0) & (var2.get() == 1): #如果选中第二个选项,未选中第一个选项 l.config(text='I love only C++') elif (var1.get() == 0) & (var2.get() == 0): #如果两个选项都未选中 l.config(text='I do not love either') else: l.config(text='I love both') #如果两个选项都选中
相对于前面学过的 print_selection
,这一段比较长,其实功能差不多,只不过加了if...elif...else
来选择控制而已即如代码注释,config
在前面已经讲过就是将参数text
的值显示,这里的var1.get() == 1
就是前面所说的var1获得的变量onvalue=1
,var1.get() == 0
即是var1
获得的变量offvalu=0
同理var2
也是如此。
运行之后的效果将会像下面的图片一样,此时不作任何操作.
Menubar 菜单
menubar 部件
下面是我们制作整个菜单栏的流程, 我们先需要加入一个 Menubar 作为整体框架, 然后再在 Menubar 中加一些部件.
##创建一个菜单栏,这里我们可以把他理解成一个容器,在窗口的上方 menubar = tk.Menu(window) ##定义一个空菜单单元 filemenu = tk.Menu(menubar, tearoff=0) ##将上面定义的空菜单命名为`File`,放在菜单栏中,就是装入那个容器中 menubar.add_cascade(label='File', menu=filemenu) ##在`File`中加入`New`的小菜单,即我们平时看到的下拉菜单,每一个小菜单对应命令操作。 ##如果点击这些单元, 就会触发`do_job`的功能 filemenu.add_command(label='New', command=do_job) filemenu.add_command(label='Open', command=do_job)##同样的在`File`中加入`Open`小菜单 filemenu.add_command(label='Save', command=do_job)##同样的在`File`中加入`Save`小菜单 filemenu.add_separator()##这里就是一条分割线 ##同样的在`File`中加入`Exit`小菜单,此处对应命令为`window.quit` filemenu.add_command(label='Exit', command=window.quit)
同样的我们在定义另一个菜单Edit
也是如此和定义的File
菜单一样 这里再来看一下效果中比较不一样的菜单就是File
中的Import
菜单, 在这个菜单选项中, 我们还能分支出更多的选项.
submenu = tk.Menu(filemenu)##和上面定义菜单一样,不过此处实在`File`上创建一个空的菜单 filemenu.add_cascade(label='Import', menu=submenu, underline=0)##给放入的菜单`submenu`命名为`Import` submenu.add_command(label="Submenu1", command=do_job)##这里和上面也一样,在`Import`中加入一个小菜单命令`Submenu1`
触发功能
counter = 0 def do_job(): global counter l.config(text='do '+ str(counter)) counter+=1
这里的功能就是没触发一次命令,counter就会+1,在label上的显示就会从 do 0 ,do 1 , do 2… 再补充一下 Tkinter 的必备步骤, 整个框架的全部代码就完美了.
这一次的效果将会像下面的图片一样.
注意这里的操作系统是苹果的 MacOS, 它的菜单栏位置和 Windows 的不一样.
Frame 框架
Frame 部件
###定义一个`label`显示`on the window` tk.Label(window, text='on the window').pack() ###在`window`上创建一个`frame` frm = tk.Frame(window) frm.pack() ###在刚刚创建的`frame`上创建两个`frame`,我们可以把它理解成一个大容器里套了一个小容器,即`frm`上有两个`frame` ,`frm_l`和`frm_r` frm_l = tk.Frame(frm) frm_r = tk.Frame(frm) ###这里是控制小的`frm`部件在大的`frm`的相对位置,此处`frm_l`就是在`frm`的左边,`frm_r`在`frm`的右边 frm_l.pack(side='left') frm_r.pack(side='right') ###这里的三个label就是在我们创建的frame上定义的label部件,还是以容器理解,就是容器上贴了标签,来指明这个是什么,解释这个容器。 tk.Label(frm_l, text='on the frm_l1').pack()##这个`label`长在`frm_l`上,显示为`on the frm_l1` tk.Label(frm_l, text='on the frm_l2').pack()##这个`label`长在`frm_l`上,显示为`on the frm_l2` tk.Label(frm_r, text='on the frm_r1').pack()##这个`label`长在`frm_r`上,显示为`on the frm_r1`
再补充一下 Tkinter 的必备步骤, 整个框架的全部代码就完美了.
这一次的效果将会像下面的图片一样.
messagebox 弹窗
messagebox部件
其实这里的messagebox
就是我们平时看到的弹窗。 我们首先需要定义一个触发功能,来触发这个弹窗 这里我们就放上以前学过的button
按钮
tk.Button(window, text='hit me', command=hit_me).pack()
通过触发功能,调用messagebox
def hit_me(): tk.messagebox.showinfo(title='Hi', message='hahahaha')
这里点击button
按钮就会弹出提示对话窗
下面给出几种形式
tk.messagebox.showinfo(title='',message='')#提示信息对话窗 tk.messagebox.showwarning()#提出警告对话窗 tk.messagebox.showerror()#提出错误对话窗 tk.messagebox.askquestion()#询问选择对话窗
如果给出如下定义就是打印出我们所选项对应的值
def hit_me(): print(tk.messagebox.askquestion(title='Hi', message='hahahaha'))
效果图
同样创建方法都是一样的形式,视频当中所给出的几种即
print(tk.messagebox.askquestion())#返回yes和no print(tk.messagebox.askokcancel())#返回true和false print(tk.messagebox.askyesno())#返回true和false print(tk.messagebox.askretrycancel())#返回true和false
pack grid place 放置位置
pack
首先我们先看看我们常用的pack()
, 他会按照上下左右的方式排列.
tk.Label(window, text='1').pack(side='top')#上 tk.Label(window, text='1').pack(side='bottom')#下 tk.Label(window, text='1').pack(side='left')#左 tk.Label(window, text='1').pack(side='right')#右
grid
接下里我们在看看grid()
, grid 是方格, 所以所有的内容会被放在这些规律的方格中.
for i in range(4): for j in range(3): tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10)
以上的代码就是创建一个四行三列的表格,其实grid
就是用表格的形式定位的。这里的参数row
为行,colum
为列,padx
就是单元格左右间距,pady
就是单元格上下间距。
place
再接下来就是place()
, 这个比较容易理解,就是给精确的坐标来定位,如此处给的(20,10)
,就是将这个部件放在坐标为(x,y)
的这个位置 后面的参数anchor=nw
就是前面所讲的锚定点是西北角。
tk.Label(window, text=1).place(x=20, y=10, anchor='nw')