第十八章 GUI库:tkinter

 
Python默认的GUI库Tk,通过Python的接口tkinter可以访问。Tk并不是PythonGUI库中最新和最好的,也没有包含最强大的GUI构建模块集,但Tk足够易用,可以使用Tk构建能够运行在大多数平台下的GUI应用。

一个很好的参考网站:https://www.runoob.com/python/python-gui-tkinter.html

18.1 tkinter 简介

tkinter是Python的默认GUI库。它基于Tk工具包,该工具包最初是为工具命令语言( Tool Command Language,TCL)设计的。Tk普及后,被移植到很多其他的脚本语言中,包括Perl、Ruby 和Python使用这些脚本语言可以开发出很多与商业软件品质相当的GUI应用。

由于tkinter是用Python 做的一个调用接口,底层仍然使用的是用C++编写的GUI库,所以在运行效率上与C/C++编写的GUI应用相当,但开发效率却远超C/C++语言。 而且由于使用的语言是Python,这也就意味着可以使用Python语言丰富而强大的第三方模块,包括网络、系统访问、XML、JSON、科学计算、深度学习、网络爬虫等。

18.2 编写第一个 tkinter 程序

如果使用的是Anaconda Python开发环境,不需要安装tkinter开发环境,因为Anaconda已经内置了。如果非要强行再安装一遍,可以使用下面的命令:

conda install -c anaconda tk

CentOS 8 安装tkinter,如果还需要在远程显示窗口需要配套安装Xming。
参考:Xming +Xshell 6 实现远程打开Linux界面

yum install python3-tk* -y
yum install tk-devel -y

使用tkinter模块开发GUI应用的基本步骤如下:

  • 导入tkinter模块。
  • 创建Tk类的实例,Tk对象表示一个窗口。
  • 对窗口进行设置,如通过title 方法设置窗口的标题,通过geometry方法设置窗口的尺寸和位置。
  • 创建控件类的实例,并将控件添加到窗口上。
  • 调用mainloop函数进入事件循环。
# 导入tkinter模块
import tkinter
# 创建Tk类的实例,也就是要显示的窗口
window = tkinter.Tk()
# 设置窗口背景为蓝色
window['background']='blue'
# 定义窗口的宽度
w = 300
# 定义窗口的高度
h = 200
# 获取屏幕宽度
ws = window.winfo_screenwidth()
# 获取屏幕高度
hs = window.winfo_screenheight()
# 根据屏幕宽度和窗口宽度计算让窗口水平居中的x坐标值
x = (ws/2) - (w/2)   
# 根据屏幕高度和窗口高度计算让窗口垂直居中的y坐标值
y = (hs/2) - (h/2)
# 设置窗口标题
window.title('第一个tkinter应用')
# 设置窗口的尺寸和位置
window.geometry('%dx%d+%d+%d' % (w, h, x, y)) 
# 创建Label对象,并将Label放在窗口上,文本显示“Hello World”
label = tkinter.Label(window, text='Hello World!')
# 使用Pack布局让Label水平居中
label.pack()
# 调用mainloop函数进入事件循环
tkinter.mainloop()

第十八章 GUI库:tkinter
Windows 和 Mac OS X 以及Linux都可以运行这个程序。其中需要了解的有以下几点:

  • tkinter 并没有直接提供让窗口居中的API,所以需要通过当前计算机屏幕的宽度和高度,以及创建的窗口的宽度和高度,计算得到窗口居中时的x坐标值和y坐标值。
  • 窗口对象的geometry 方法用于设置窗口的尺寸和位置。窗口尺寸和位置需要通过一一个字符串描述,格式是width*height+x+y,例如,200*100+300+150表示窗口的宽度是200,高度是100,窗口左上角的横坐标是300,窗口左上角的纵坐标是150。
  • 如果要想将控件显示在窗口上,则在创建控件对象时,需要将窗口对象作为控件类的第一个参数传入控件对象,例如,tkinter.Label(window, text=‘Hello World!’)。
  • Label对象的pack方法可以让Label通过pack布局摆放在窗口上。

18.3 布局

tkinter有三种布局管理方式:pack、grid和place。这三种布局在窗口中不可以混用,也就是说同时只能使用一种布局。tkinter 中布局的主要工作是将控件放置在窗口上,并根据具体的布局调整控件的位置和控件的尺寸。

18.3.1 pack 布局

pack布局是三种布局中最常用的。另外两种布局需要精确指定控件具体的位置,而pack布局可以指定相对位置,精确的位置会由pack系统自动设置。这也使得pack布局没有另外两种布局的方式灵活。所以pack布局是简单应用的首选布局。

1. 控件水平居中

from tkinter import *  
  

window = Tk()
# 窗口标题
window.title('水平居中')
# 窗口宽、高
window.geometry('300x200') 
# 窗口背景颜色
window['background']='blue'
# 以下3个都使用了pack布局
# 在窗口上放置一个Label控件,背景红色,文字白色
Label(window, text="复仇者联盟", bg="red", fg="white").pack()  
# 在窗口上放置一个Label控件,背景绿色,文字黑色
Label(window, text="正义联盟", bg="green", fg="black").pack()  
# 在窗口上放置一个Label控件,背景黄色,文字蓝色
Label(window, text="天启星", bg="yellow", fg="blue").pack()  
  
mainloop()  

第十八章 GUI库:tkinter
2. 水平填充

通过将pack方法的fill关键字参数值设为x’,可以让控件水平填充,也就是在水平方向充满整个窗口。

from tkinter import *  

window = Tk()
window.title('水平填充')
window['background']='blue'
window.geometry('300x200')  
# 通过fill关键字填充
w = Label(window, text="复仇者联盟", bg="red", fg="white")  
w.pack(fill=X)  
w = Label(window, text="正义联盟", bg="green", fg="black")  
w.pack(fill=X)  
w = Label(window, text="保卫地球", bg="yellow", fg="blue")  
w.pack(fill=X)  

mainloop()

第十八章 GUI库:tkinter
3. 设置边距
tkinter布局可以对控件的外边距和内边距进行设置。外边距和内边距又分为水平外边距、垂直外边距、水平内边距和垂直内边距。

  • 水平外边距。通过指定pack方法的padx关键字参数可以设置控件的水平外边距。
from tkinter import *  
  
window = Tk()
window.title('设置水平外边距')
window['background']='blue'
window.geometry('300x200')  

# 通过关键字padx指定控件与窗口左右边缘的距离
w = Label(window, text="复仇者联盟", bg="red", fg="white")  
w.pack(fill=X,padx=10)  
w = Label(window, text="正义联盟", bg="green", fg="black")  
w.pack(fill=X,padx=20)  
w = Label(window, text="保卫地球", bg="yellow", fg="blue")  
w.pack(fill=X,padx=10)  

mainloop() 

第十八章 GUI库:tkinter

  • 垂直外边距。通过指定pack方法的pady关键字参数可以设置控件的垂直外边距。
from tkinter import *  
  
window = Tk()
window.title('设置垂直外边距')
window['background']='blue'
window.geometry('300x200')  
# 通过关键字pady指定控件垂直外边距
w = Label(window, text="复仇者联盟", bg="red", fg="white")  
w.pack(fill=X,pady=10)  
w = Label(window, text="正义联盟", bg="green", fg="black")  
w.pack(fill=X,pady=20)  
w = Label(window, text="保卫地球", bg="yellow", fg="blue")  
w.pack(fill=X,pady=10)  
mainloop() 

第十八章 GUI库:tkinter

  • 同时设置水平外边距和垂直外边距。在pack方法中padx关键字参数和pady关键字参数可以同时使用,这样控件就会同时拥有水平外边距和垂直外边距。
from tkinter import *

window = Tk()
window.title('同时设置水平外边距和垂直外边距')
window['background'] = 'blue'
window.geometry('300x200')

# 同时设置水平外边距和垂直外边距
w = Label(window, text="复仇者联盟", bg="red", fg="white")
w.pack(fill=X, padx=10, pady=10)
w = Label(window, text="正义联盟", bg="green", fg="black")
w.pack(fill=X, padx=20, pady=20)
w = Label(window, text="保卫地球", bg="yellow", fg="blue")
w.pack(fill=X, padx=10, pady=10)
mainloop()

第十八章 GUI库:tkinter

  • 内边距。内边距是指控件中的内容(如文本)到控件边缘的距离。通过pack方法的ipadx关键字参数可以设置控件的水平内边距,通过ipady关键字参数可以设置控件的垂直内边距。ipadx、ipady可以单独使用,也可以混合使用,当然,也可以与padx和pady一起使用。
from tkinter import *  
  
window = Tk()
window.title('内边距')
window['background']='blue'
window.geometry('300x200')  
w = Label(window, text="复仇者联盟", bg="red", fg="white")  
w.pack(fill=X,ipady=30,padx=10, pady=10)  
w = Label(window, text="正义联盟", bg="green", fg="black")  
w.pack(fill=X,ipadx=10,ipady=20)  
w = Label(window, text="保卫地球", bg="yellow", fg="blue")  
w.pack(fill=X,ipadx=10,padx=10, pady=10)  
mainloop()

第十八章 GUI库:tkinter
4. 水平排列

设置pack方法的side关键字参数可以让多个控件按水平方向从左到右或从右到左排列。

  • 从左到右水平排列。将pack 方法的side 关键字参数值设为LEFT, 会让控件从左到右水平排列。
from tkinter import *  
  
window = Tk()
window.title('从左到右水平排列')
window['background']='blue'
window.geometry('400x100')  

# 设置控件从左到右排列side=LEFT
w = Label(window, text="复仇者联盟", bg="red", fg="white")  
w.pack(padx=10,pady=10,side=LEFT)  
w = Label(window, text="正义联盟", bg="green", fg="black")  
w.pack(padx=10,pady=10,side=LEFT) 
w = Label(window, text="保卫地球", bg="yellow", fg="blue")  
w.pack(padx=10,pady=10,side=LEFT) 
mainloop() 

第十八章 GUI库:tkinter

  • 从右到左水平排列。将pack方法的side关键字参数的值设为RIGHT,可以让控件从右向左水平排列,当然,LEFT和RIGHT可以混合使用。使用LEFT的控件会从左到右水平排列,使用RIGHT的控件会从右到左水平排列。
from tkinter import *  

window = Tk()
window.title('混合水平排列')
window['background']='blue'
window.geometry('400x100')  
# 从右到左排列
w = Label(window, text="复仇者联盟", bg="red", fg="white")  
w.pack(padx=10,pady=10,side=RIGHT)  
w = Label(window, text="正义联盟", bg="green", fg="black")  
w.pack(padx=10,pady=10,side=RIGHT) 
w = Label(window, text="保卫地球", bg="yellow", fg="blue")  
w.pack(padx=10,pady=10,side=LEFT) 
mainloop() 

第十八章 GUI库:tkinter

18.3.2 place 布局

place布局允许通过place方法的参数指定控件的位置(x和y)和尺寸(width和height)。这4个值通过控件对象的place方法的x、y、width和height 四个参数就可以设置。

import tkinter as tk
import random

window = tk.Tk()
window.title('place布局')
window['background'] = 'blue'
# 设置窗口的宽、高; 以及窗口左上角的横坐标、纵坐标
window.geometry("300x200+30+30")
# 控件中显示的文本内容
languages = ['Python', 'Swift', 'C++', 'Java', 'Kotlin']
labels = range(5)
# 循环产生5个控件
for i in range(5):
    # 随机产生背景色的三原色
    ct = [random.randrange(256) for x in range(3)]
    # 取亮度
    brightness = int(round(0.299 * ct[0] + 0.587 * ct[1] + 0.114 * ct[2]))
    # 得到背景色的十六进制形式
    ct_hex = "%02x%02x%02x" % tuple(ct)
    bg_colour = '#' + "".join(ct_hex)
    # 创建控件,并根据亮度设置文本颜色为白色和黑色
    label = tk.Label(window,
                     text=languages[i],
                     fg='White' if brightness < 120 else 'Black',
                     bg=bg_colour)
    # place布局,通过place方法设置控件的位置和尺寸
    label.place(x=50, y=30 + i * 30, width=120, height=25)

window.mainloop()

第十八章 GUI库:tkinter

18.3.3 grid 布局

grid布局顾名思义,是将控件作为单元格(cell) 放到一个表格里,类似于二维表。每一个单元格会根据其中的控件的尺寸调整自己的尺寸。通过调用控件对象的grid方法可以让控件按着表格形式摆放。grid方法需要指定row和column两个关键字参数,其中row表示当前的行(从0开始),column表示当前的列(从0开始)。

示例:创建18个控件,这18个控件摆放在一个6*3的表格中。

from tkinter import *  
window = Tk() 
window.title('grid布局') 
# 设置窗口背景色为灰色
window['background'] = '#AAA'
# 设置创空的尺寸和位置
window.geometry("400x150+30+30")  
# 设置中间一列的控件的背景颜色   
colours = ['red','green','orange','white','yellow','blue']  

r = 0  
# 动态产生18个控件
for c in colours:  
    # relief关键字参数表示控件边缘的效果
    Label(window,text=c, relief=RIDGE,width=15).grid(row=r,column=0)  
    Label(window,bg=c, relief=SUNKEN,width=10).grid(row=r,column=1)  
    Label(window,text=c, relief=RIDGE,width=15).grid(row=r,column=2)  
    r = r + 1    
mainloop()  

第十八章 GUI库:tkinter

18.4 控件

由于tkinter依托于强大的Python语言,所以学习tkinter 其实主要就是学习布局和控件,然后就可以利用Python语言海量的原生模块和第三方模块编写拥有强大功能的GUI程序。

18.4.1 Label 控件和 Button 控件

Label类的构造方法需要传入一些必要的参数值,例如,第1个参数通常是窗口对象,然后通过text参数设置要显示的文本,通过fg属性设置文本的演示,通过width和height参数设置Label控件的宽度和高度。

Label(window, text='Hel1o World', fg='blue', bg='green', width=20, height=2)

除了上述的这些参数外,还可以通过font参数设置Label控件中显示文本的字体和字号。

Label(window,text='Hello World', fg='blue', bg='green', font=('Arial', 12), width=20,height=2)

如果要获取和设置Label控件中的文本内容,有一个非常简单的方法,就是将一个Label 控件与一个变量绑定,如果变量改变,那么Label控件中显示的文本也会改变。

var = StringVar()
Label(window, textvariable=var)
# 设置Label控件中的文本
var.set('Hello World')
# 获取并输出Label控件中的文本
print (var.get())

Button是tkinter中另外一个非常常用的控件,主要用来与用户交互,用户会通过单击按钮通知程序完成一些任务,而程序一般在完成任务后,会给用户一些反馈,例如,会在Console中输出消息,会弹出一个对话框等。

Button控件与Label控件在使用上几乎是一样的,只是Button控件还需要一个处理单击事件的回调函数,这个回调函数需要通过Button类的command关键字参数指定。

示例:创建了 两个Label 控件以及两个Button控件,通过单击第1个Button控件,可以更换Label控件中的文本,单击第2个Button控件,可以获取第2个Label控件的文本,并在Console中显示。

import tkinter as tk
import random

window = tk.Tk()
window.title('Label控件和Button控件')
window['background'] = 'blue'
window.geometry("400x300+30+30")
# 创建控件,设置字体,字号
label1 = tk.Label(window,
                  text='Hello World',
                  bg='green', font=('Arial', 12), width=20, height=2)
label1.pack()
# 创建一个绑定控件的变量
var = tk.StringVar()
# 初始化变量
var.set('Hello World')
# 创建控件并与var变量绑定
label2 = tk.Label(window,
                  textvariable=var,
                  fg='blue',
                  bg='yellow', font=('Arial', 12), width=15, height=2)
# 使用pack布局摆放控件,并设置控件垂直外边距
label2.pack(pady=20)
onHit = False

# 第1个按钮的单击回调函数
def hitMe():
    global onHit
    if onHit == False:
        onHit = True
        var.set('世界你好')
    else:
        onHit = False
        var.set('Hello World')
   
# 创建第1个Button控件,并与hitMe函数绑定
button1 = tk.Button(window, text='点击改变第2个控件内容', command=hitMe)
button1.pack()

# 第2个按钮的单击回调函数
def getLabelText():
    # 输出控件中的内容
    print(var.get())

# 创建第2个Button控件,并与getLabelText函数绑定
button2 = tk.Button(window, text='获取Label控件的文本到控制台', command=getLabelText)
button2.pack(pady=20)

window.mainloop()

第十八章 GUI库:tkinter

18.4.2 Entry 控件与 Text 控件

Entry控件与Text控件都是用来输入文本的。Entry 是单行文本输入控件,而Text 是多行文本输入控件,而且支持图像、富文本等格式。

示例:创建了两个Entry控件和一个Text控件。其中一个Entry控件回显星号(*), 当在这个Entry控件中输入文本时,会在另一个Entry控件中显示同样的文本。在Text 控件中插入了两个本地图像,在两个图像中间插入了大字体的文本。

import tkinter as tk

window = tk.Tk() 
window.title('Entry控件与Text控件') 
window['background']='blue'
window.geometry("600x500+30+30")

# 变量绑定了第1个Entry控件      
entryVar1 = tk.StringVar()
# 在第1个Entry控件中输入文本时回调的函数
def callback():
    # 更新第2个控件中的文本
    entryVar2.set(entryVar1.get())   
# 将第1个Entry控件与entryVar1绑定,w表示当写入时调用callback函数,其中a,b,c是Lambda表达式
# 传入3个参数,否则会抛出异常(本例中用不到这3个参数)
entryVar1.trace("w", lambda a,b,c: callback())

# 创建第1个Entry控件
entry1 = tk.Entry(window,textvariable=entryVar1,show='*')
# 对第1个控件使用pack布局
entry1.pack(pady = 10)
# 该变量绑定了第2个Entry控件
entryVar2 = tk.StringVar()
# 创建第2个Entry控件
entry2 = tk.Entry(window,textvariable=entryVar2)
# 对第2个控件使用pack布局
entry2.pack(pady = 10)

# 创建Text控件
text = tk.Text(window)
# 使用pack布局
text.pack(pady = 10)
# 由于Text控件只支持少数几种图像(gif、bmp等),不支持jpg、png,所以要插入这些不支持格式的图像,需要用PIL处理下
from PIL import Image, ImageTk
# 装载 pic.png
pic = Image.open('pic.png')
photo1=ImageTk.PhotoImage(pic)
# 在Tetx控件的结尾插入图像
text.image_create(tk.END, image=photo1)
# 设置字体、字号,需要通过big引用
text.tag_configure('big', font=('Arial', 25, 'bold'))
# 在Tetx控件的结尾插入文本,并使用big指定的字体属性
text.insert(tk.END, "涛哥",'big')
ha = Image.open('ha.jpg')
photo2 = ImageTk.PhotoImage(ha)
# 在Text控件的结尾插入图像
text.image_create(tk.END, image=photo2)

window.mainloop()  

第十八章 GUI库:tkinter

18.4.3 Radiobutton 控件

Radiobutton是单选按钮控件,通常是两个或两个以上的Radiobutton控件一起 使用,同时只能有一个Radiobutton控件处于选中状态。为了达到这个目的,需要多个Radiobutton控件与同一个变量和选择变化事件绑定。

import tkinter as tk

window = tk.Tk()
window.title('Radiobutton控件')
window.geometry('300x200')
window['background'] = 'blue'

# 该变量同时与3个Radiobutton控件绑定
var = tk.StringVar()
label = tk.Label(window, bg='yellow', width=20, text='empty')
label.pack()
# 默认选择第一个Radiobutton控件
var.set('A')
# 当Radiobutton的选择变化后,会调用该函数
def printSelection():
    # 更新Label控制的文本,显示当前用户选择的状态
    label.config(text='你已经选择了' + var.get())
printSelection()
# 创建第1个Radiobutton控件
r1 = tk.Radiobutton(window, text='选项A',
                    variable=var, value='A',
                    command=printSelection)
r1.pack()
# 创建第2个Radiobutton控件
r2 = tk.Radiobutton(window, text='选项B',
                    variable=var, value='B',
                    command=printSelection)
r2.pack()
# 创建第3个Radiobutton控件
r3 = tk.Radiobutton(window, text='选项C',
                    variable=var, value='C',
                    command=printSelection)
r3.pack()
window.mainloop()

第十八章 GUI库:tkinter

18.4.4 Checkbutton 控件

Checkbutton是多选控件,通常是两个或两个以上Checkbutton控件一起使用。Checkbutton控件通过Checkbutton 类构造方法的variable 关键字参数与变量绑定,通过onvalue 关键字参数指定Checkbutton选中状态的值,通过offvalue关键字参数指定Checkbutton未选中状态的值。

import tkinter as tk

window = tk.Tk()
window.title('Checkbutton控件')
window.geometry('300x200')
window['background'] = 'blue'
label = tk.Label(window, bg='yellow', width=30, text='empty')
label.pack()

# Checkbutton控件状态变化时调用的函数
def printSelection():
    text = ''
    if var1.get() == 1:
        text += ' ' + c1.cget('text')
    if var2.get() == 1:
        text += ' ' + c2.cget('text')
    if var3.get() == 1:
        text += ' ' + c3.cget('text')
    if var4.get() == 1:
        text += ' ' + c4.cget('text')
    label.config(text=text)

# 创建4个变量并与4个Checkbutton控件绑定
var1 = tk.IntVar()
var2 = tk.IntVar()
var3 = tk.IntVar()
var4 = tk.IntVar()
c1 = tk.Checkbutton(window, text='Python', variable=var1, onvalue=1, offvalue=0,width=20, command=printSelection)
c2 = tk.Checkbutton(window, text='C++', variable=var2, onvalue=1, offvalue=0,width=20, command=printSelection)
c3 = tk.Checkbutton(window, text='Kotlin', variable=var3, onvalue=1, offvalue=0,width=20, command=printSelection)
c4 = tk.Checkbutton(window, text='Swift', variable=var4, onvalue=1, offvalue=0, width=20, command=printSelection)
# 很难左对齐
c1.pack()
c2.pack()
c3.pack()
c4.pack()

window.mainloop()

第十八章 GUI库:tkinter

18.4.5 Scale 控件

Scale是一个滑块组件,支持水平滑动和垂直滑动。通过滑块的滑动可以在有限的范围内进行数值的设置。Scale控件需要设置的属性比较多(通过Scale类的构造方法设置),下面是Scale控件需要设置的主要属性。

  • label: 在Scale 控件旁边显示的标签文本,水平滑块控件在上方显示,垂直滑块控件在右侧显示。
  • length: Scale 控件的长度。
  • from_: 滑块能设置的最小值,也是Scale控件的起始值。
  • to: 滑块能设置的最大值,也是Scale控件的结束值。
  • tickinterval: Scale 控件刻度的步长。
  • resolution: 滑块能滑动的步长。
  • command: 指定滑动事件对应的回调函数。
  • orient:设置Scale 控件类型,HORIZONTAL表示水平Scale 控件,VERTICAL表示垂直Scale控件。
import tkinter as tk

window = tk.Tk()
window.title('Scale控件')
window.geometry('300x400')
window['background'] = 'blue'
label1 = tk.Label(window, bg='yellow', width=20)
label1.pack()

# 水平Scale控件滑动时调用的函数
def printSelection1(v):
    # 在Label控件中显示水平Scale控件的当前值
    label1.config(text='当前值:' + v)
# 创建水平控件Scale控件
scale1 = tk.Scale(window, label='拖我', from_=5, to=11, orient=tk.HORIZONTAL,
             length=200, tickinterval=2, resolution=0.01, command=printSelection1)
scale1.pack(pady = 10)

label2 = tk.Label(window, bg='yellow', width=20)
label2.pack()
# 垂直Scale控件滑动时调用的函数
def printSelection2(v):
    label2.config(text='当前值:' + v)
# 创建垂直Scale控件
scale2 = tk.Scale(window, label='拖我', from_=5, to=11, orient=tk.VERTICAL,
             length=200, tickinterval=2, resolution=0.01, command=printSelection2)
scale2.pack(pady = 10)

window.mainloop()

第十八章 GUI库:tkinter

18.4.6 Listbox 控件

Listbox是一个列表控件,顾名思义,就是可以显示一组值的控件。Listbox 对象提供了insert 方法和delete方法用于向Listbox控件添加和删除列表项,如果要编辑列表项,可以先删除要编辑的列表项,然后在该位置再插入新的列表项,也就是先删除,后插入。Listbox控件最常用的事件就是列表项选择事件,可以使用Listbox 对象的bind 方法绑定ListboxSelect事件。代码如下:

#事件名两侧要用“<<”和“>>”括起来
bind('<<ListboxSe1ect>>', onselect)

示例:

import tkinter as tk

window = tk.Tk()
window.title('Listbox控件')
window.geometry('250x300')
window['background'] = 'blue'

var1 = tk.StringVar()
l = tk.Label(window, bg='yellow', width=10, textvariable=var1)
l.pack()

# 与Listbox控件绑定的变量
var2 = tk.StringVar()
var2.set((11,22,33,44))
# 创建Listbox控件
lb = tk.Listbox(window, listvariable=var2)
# Listbox控件选择列表时调用的函数
def onselect(evt):
    w = evt.widget
    value = w.get(w.curselection())
    # 将当前选中的列表项文本显示在Label控件上
    var1.set(value)
# 将ListboxSelect事件与onselect函数绑定
lb.bind('<<ListboxSelect>>', onselect)
# 选择第1个列表项
lb.selection_set(first=0)
value = lb.get(lb.curselection())
# 在Label控件上显示第1个列表项的文本
var1.set(value)


list_items = [11111,22222,3333,4444]
# 向Listbox控件插入4个列表项
for item in list_items:
    lb.insert('end', item)
# 在第n个位置插入列表项
lb.insert(1, 'Python')
lb.insert(2, 'Kotlin')
lb.insert(3, 'Swift')
# 删除第3个列表项
lb.delete(2)
lb.pack(pady = 20)

window.mainloop()

第十八章 GUI库:tkinter

18.5 向窗口添加菜单

要想在窗口中添加菜单,首先需要创建Menu对象。第1个创建的Menu对象表示菜单的根。因为在创建这个Menu对象时,Menu类构造方法的参数是窗口对象,这样就将菜单与窗口绑定了。然后再创建Menu对象,Menu类构造方法的参数就是父菜单对应的Menu对象。为了在一个菜单项上添加子菜单,还需要调用Menu对象的add_cascade方法。

import tkinter as tk

window = tk.Tk()
window.title('MenuBar')
window.geometry('300x200')

label = tk.Label(window, width = 20, bg='yellow')
label.pack()
# 计数器,每选择一次菜单项,计数器就会加1
counter = 1
# 选择菜单项后调用的函数
def menuClick():
    global counter
    label.config(text='第 '+ str(counter) + ' 次点击')
    counter+=1
# 创建根菜单
menubar = tk.Menu(window)
# 创建"文件"菜单项
filemenu = tk.Menu(menubar)
# 将"文件"菜单项添加到根菜单上
menubar.add_cascade(label='文件', menu=filemenu)
# 为"文件"菜单项添加新的子菜单项,通过command 关键字参数绑定菜单项单击回调函数
filemenu.add_command(label='新建', command=menuClick)
filemenu.add_command(label='打开', command=menuClick)
filemenu.add_command(label='保存', command=menuClick)
# 添加一个分隔条
filemenu.add_separator()
# 添加"退出"菜单项,并指定选择该菜单项调用的是系统提供的回调函数,选择该菜单项后退出整个程序
filemenu.add_command(label='退出', command=window.quit)
# 创建"编辑"菜单项
editmenu = tk.Menu(menubar, tearoff=0)
# 为"编辑"菜单项添加新的子菜单项
menubar.add_cascade(label='编辑', menu=editmenu)
editmenu.add_command(label='剪切', command=menuClick)
editmenu.add_command(label='复制', command=menuClick)
editmenu.add_command(label='粘贴', command=menuClick)

submenu = tk.Menu(filemenu)
# 在"文件"菜单项下添加带子菜单项的"导入"菜单项
filemenu.add_cascade(label='导入', menu=submenu)
submenu.add_command(label="导入文本文件", command=menuClick)
submenu.add_command(label="导入pdf文件", command=menuClick)
# 在窗口上显示菜单
window.config(menu=menubar)

window.mainloop()

第十八章 GUI库:tkinter

18.6 对话框

对话框与窗口类似,只是对话框都是模态的,也就是说,一旦显示了对话框,除非将其关闭,否则不能访问对话框后面窗口上的控件。使用messagebox模块中相应API可以显示不同样式的对话框。

import tkinter as tk
import tkinter.messagebox

window = tk.Tk()
window.title('my window')
window.geometry('200x200')

# 调用该函数会依次执行各种类型的对话框,只有前一个对话框关闭,才会显示后一个对话框
def hit_me():
    # return 'ok'
    tk.messagebox.showinfo(title='信息对话框', message='这是我要的信息')   
    # return 'ok'
    tk.messagebox.showwarning(title='警告对话框', message='这是警告信息')   
    # return 'ok'
    tk.messagebox.showerror(title='错误对话框', message='这是错误信息')   
    # return 'yes' , 'no'
    print(tk.messagebox.askquestion(title='询问对话框', message='你要干嘛?'))   
    # return True, False
    print(tk.messagebox.askyesno(title='yes/no', message='请给出你的选择'))   
    # return True, False
    print(tk.messagebox.askokcancel(title='ok/cancal', message='确定/取消'))   
    # return, True, False, None
    print(tk.messagebox.askyesnocancel(title="yes/no/cancel", message="请给出你的选择"))     

tk.Button(window, text='hit me', command=hit_me).pack()
window.mainloop()

第十八章 GUI库:tkinter

第十八章 GUI库:tkinter
第十八章 GUI库:tkinter
第十八章 GUI库:tkinter
第十八章 GUI库:tkinter

上一篇:Tkinter笔记(1)——概述


下一篇:cp8_1_1.py