学习环境: Windows,python,PyCharm
1. tkinter的使用
使用tkinter模块,只需要简单地导入就可以了。可以使用以下三种方法。
import tkinter
from tkinter import *
import tkinter as tk
可以选择自己顺手的方式。
2. tkinter的简单操作
首先,Hello world
作为学习的传统,先来一个经典的hello world程序。
import tkinter as tk
root = tk.Tk() # 创建底层窗口,每个程序中只能存在一个,并应在其他组件前创建。
w = tk.Label(root, text='Hello world!') # 创建一个Label组件
w.pack() # 将组件可视化
root.mainloop() #
知识点: Label组件可以显示文本、图标或其他图像
Hello Again!
当你试图写一个较大的程序时,将程序包装成不同的类或许是一个好方法。如下例:
from tkinter import *
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text='Quit', fg='red'
, command=frame.quit)
self.button.pack(side=LEFT)
self.hi_there = Button(frame, text='Hello',
command=self.say_hi)
self.hi_there.pack(side=LEFT)
def say_hi(self):
print('hi there, everyone!')
root = Tk()
app = App(root)
root.mainloop()
上例中,新建了一个App类。其构造函数__inti__通过一个父类组件(master)调用并生成一系列的子组件。该构造函数首先创建了一个Frame组件。一个Frame就是一个简单的容器,在上例中用来保存另外两个组件。
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
将新建的Frame组件保存在变量frame中,并立即调用pack方法使其可视化。
之后又创建了两个Button组件,作为frame的子组件。
self.button = Button(frame, text='Quit', fg='red'
, command=frame.quit)
self.button.pack(side=LEFT)
self.hi_there = Button(frame, text='Hello',
command=self.say_hi)
self.hi_there.pack(side=LEFT)
在创建Button组件时,我们使用了一些参数:text命名Button,fg(foreground的简写)设置前景色,command指定调用函数(当点击Button时会调用该函数)。
它们的pack方法中使用了side=LEFT,意味着Button组件在frame中会尽量地向左排。默认为TOP。
然后编写‘hello’Button的调用函数:
def say_hi(self):
print('hi there, everyone!')
最后,创建底层界面,实例化App类:
root = Tk()
app = App(root)
root.mainloop()
注意!! 当你只需要创建一个组件,而在之后不再对其有所操作,那最好使用下面的写法:
Button(frame, text="Hello", command=self.hello).pack(side=LEFT)
来代替
w = Button(frame, text="Hello", command=self.hello)
w.pack(side=LEFT)
3. tkinter的组件
再来了解一下tkinter都支持哪些组件
组件名 | 功能介绍 |
---|---|
Button | 创建一个按钮,用于执行命令或其他操作 |
Canvas | 创建结构化图形。本组件可以用来绘制图形和图表,创建图形编辑器,并实现定制组件。 |
Checkbutton | 表示可以具有两个不同值的变量。单击按钮在值之间切换。 |
Entry | 创建一个简单的文本输入框 |
Frame | 创建一个容器组件。可以有边框和背景,用于在创建appllication或对话框布局时对其他组件进行分组。 |
Label | 显示文本或图像 |
Listbox | 显示备选项的列表。可以将listbox配置为单选或多选。 |
Menu | 一个菜单面板。用于实现下拉菜单和弹出菜单 |
Menubutton | 创建一个菜单按钮,用于实现下拉菜单。 |
Message | 显示一个文本。类似于label组件,但可以自动将文本包装成给定的宽度或宽高比。 |
Radiobutton | 表示变量的一个值,该变量可以具有多个值中的一个。单击按钮将变量设置为该值,并清除与同一变量关联的所有其他radiobutton。 |
Scale | 允许通过拖动“滑块”设置数值。 |
Scrollbar | 与Canvas、Entry、Listbox和Text组件一起使用的标准滚动条。 |
Text | 格式化的文本显示。允许您显示和编辑具有各种样式和属性的文本。还支持嵌入式图像和窗口。 |
Toplevel | 显示为一个单独的顶层窗口的容器组件。 |
LabelFrame | Frame组件的一个变体,可以同时绘制边框和标题。 |
PanedWindow | 一个容器组件,它在可调整大小的窗格中组织子组件。 |
Spinbox | Entry组件的一个变体,用于从范围或有序集合中选择值。 |
以上组件除了其各自特有定义的方法外,还均支持Misc、几何设计方法和配置管理方法
3.1 Misc
底层窗口(即Tk())和组件类将Misc当作一个mixin使用。而mixin表示一个被设计成使用多重继承与其他类相结合的类。
3.2 几何设计方法——geometry management methods
- Grid:grid几何管理会创造一个表格式的布局,可以在这个二维网格中布局组件
- Pack:pack几何管理把组件打包放置在父组件上,可以将这些组件看成一些矩形块。
- Place:place几何管理会将组件放置在指定的确定位置
3.3 配置管理方法——configuration management methods
组件类将Misc类与geometry mixin混合,并通过cget和configure方法以及部分dictionary接口添加配置管理。后者可用于设置和查询单个选项。
4. 组件配置
为了控制组件的显示,通常更多使用options而不是调用方法。典型的options有text,color,size和command等。所有的核心组件都有相同的配置接口:
4.1 配置接口
4.1.1 组件的配置接口——widgetclass(master, option=value, …)
widgetclass可以是上面提到的任一组件类。在给定master(即基层窗口Tk())上,按照指定的options创建一个该组件类的实例。所有options都有默认值,所有创建最简单的组件时可以不指定options。
4.1.2 string的配置接口——cget(“option”)
返回option的当前指定值。option名和返回值都是字符串。
4.1.3 config(option=value, …) or configure(option=value, …)
设置一个或多个options
4.1.4 list的配置接口——keys()
返回一个该组件可设置options的列表。
5. 组件式样
tkinter所有标准组件都有一系列式样options,允许用户自定义颜色,字体和其他组件可视化部分。
5.1 颜色
大多数组件都支持用户自定义组件和文本颜色,方法包括background和foreground。设置颜色时,可以直接使用颜色名如red,或使用RGB值。
5.2 字体
组件设置字体通常使用font。设置方式主要有以下几种
- 描述法:将字体设置写成一个元组,如(“Times”, 10, “bold”),而如果字体名不包括空格,还可以写成:“Times 10 bold”
- 自定义字体法:使用tkinter模块的font类进行自定义,如:
import tkinter.font as tkFont
from tkinter import *
root = Tk()
my_font = tkFont.Font(family="Times", size=10, weight=tkFont.BOLD, slant=tkFont.ITALIC, underline=1)
button = Button(root, text='button', font=my_font)
button.pack()
root.mainloop()
- 使用系统字体:系统自带字体包括:ansi, ansifixed, device, oemfixed, system, and systemfixed。
5.3 文本格式化
文本默认居中。可通过justify设置为LEFT或RIGHT。可通过wraplength设置文本的宽度。
5.4 边框
- borderwidth(或bd)设置组件边框宽度,默认为1或2个像素。
- relief设置3D边框,可选项有SUNKEN, RAISED, GROOVE, RIDGE,和FLAT。
- highlightcolor:此选项用于在组件具有键盘焦点时绘制突出显示区域。它通常是黑色,或其他一些鲜明的对比颜色。
- highlightbackground:此选项用于在组件没有键盘焦点时绘制突出显示区域。它通常与组件背景相同。
- highlightthickness:突出显示区域的宽度,以像素为单位。
5.5 光标
cursor:此选项控制当鼠标移动到组件上时要使用的鼠标光标。
6. 事件与绑定
将一个事件和函数或方法绑定。如widget.bind(event, handler)
捕捉鼠标点击:
from tkinter import *
root = Tk()
def callback(event):
print ("clicked at", event.x, event.y)
frame = Frame(root, width=100, height=100)
frame.bind("<Button-1>", callback)
frame.pack()
root.mainloop()
捕捉键盘事件:
from tkinter import *
root = Tk()
def key(event):
print ("pressed", repr(event.char))
def callback(event):
frame.focus_set()
print ("clicked at", event.x, event.y)
frame = Frame(root, width=100, height=100)
frame.bind("<Key>", key)
frame.bind("<Button-1>", callback)
frame.pack()
root.mainloop()
事件通常写成字符串形式,具体语法:< modifier-type-detail >。
注意!本部分的事件语法中去掉空格后才能使用
最常见的事件:
事件名 | 事件描述 |
---|---|
< Button-1 > | 在组件上按下鼠标,1表示左键,2表示中键,3表示右键 |
< B1-Motion > | 在按下鼠标时,同时移动鼠标 |
< ButtonRelease-1 > | 松开鼠标 |
< Double-Button-1 > | 双击鼠标 |
< Enter > | 鼠标指针进入组件,而不是用户敲击Enter键 |
< Leave > | 鼠标指针离开组件 |
< FocusIn > | 键盘焦点被移动到这个组件,或者这个组件的子组件。 |
< FocusOut > | 键盘焦点从这个组件离开,到另一个组件 |
< Return > | 用户敲击Enter键 |
< Key > | 用户敲击任何键 |
a | 用户输入了一个“a”。大多数可打印字符可以按原样使用。例外情况是空格(< spac e>)和小于(< less >)。注意,1是键盘绑定,而< 1 >是按钮绑定。 |
< Shift-Up > | 用户按下向上箭头,同时按住Shift键。Alt, Shift, and Control都可使用 |
< Configure > | 组件大小改变。并返回新的width和height |
事件属性:
属性名 | 属性描述 |
---|---|
widget | 产生事件的组件 |
x,y | 鼠标的当前位置,以像素为单位。 |
x_root, y_root | 当前鼠标相对于屏幕左上角的位置,以像素为单位。 |
char | 字符代码字符串(仅限键盘事件)。 |
keysym | 键符号(仅限键盘事件)。 |
keycode | 键码(仅限键盘事件)。 |
num | 按钮编号(仅限鼠标按钮事件)。 |
width, height | 组件的新大小(以像素为单位)(仅Configure事件)。 |
type | 事件类型 |
7. 应用程序窗口
7.1 创建底层窗口
from tkinter import *
root = Tk()
# 置于root窗口的组件在这里创建
root.mainloop()
7.2 再创建一个窗口
from tkinter import *
root = Tk()
# 置于root窗口的组件在这里创建
top = Toplevel()
# 置于top窗口的组件在这里创建
root.mainloop()
7.3 创建菜单组件
tkinter中,通过Menu类创建菜单组件实例,用add方法添加条目:
- add_command(label=string, command=callback):添加一个普通菜单项。
- add_separator():添加分隔线。
- add_cascade(label=string, menu=menu instance):添加子菜单。
from tkinter import *
def callback():
print("called the callback!")
root = Tk()
# create a menu
menu = Menu(root)
root.config(menu=menu)
filemenu = Menu(menu)
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="New", command=callback)
filemenu.add_command(label="Open...", command=callback)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=callback)
helpmenu = Menu(menu)
menu.add_cascade(label="Help", menu=helpmenu)
helpmenu.add_command(label="About...", command=callback)
mainloop()
7.4 创建工具栏
from tkinter import *
root = Tk()
def callback():
print("called the callback!")
# create a toolbar
toolbar = Frame(root)
b = Button(toolbar, text="new", width=6, command=callback)
b.pack(side=LEFT, padx=2, pady=2)
b = Button(toolbar, text="open", width=6, command=callback)
b.pack(side=LEFT, padx=2, pady=2)
toolbar.pack(side=TOP, fill=X) # fill=X将调整toolbar的大小,以达到完全填满的状态。
mainloop()
7.5 创建状态栏
最简单的方法就是创建一个Label组件
status = Label(master, text="", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
新建状态类
from tkinter import *
class StatusBar(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.label = Label(self, bd=1, relief=SUNKEN, anchor=W)
self.label.pack(fill=X)
def set(self, format, *args):
self.label.config(text=format % args)
self.label.update_idletasks()
def clear(self):
self.label.config(text="")
self.label.update_idletasks()
root = Tk()
status = StatusBar(root)
status.pack(side=BOTTOM, fill=X)
mainloop()
8. 标准对话框
tkinter模块提供了消息框的接口。它含有7个函数:showinfo, showwarning, showerror, askquestion, askokcancel, askyesno,和askretrycancel,并且有相同的使用语法:tkinter.function(title, message [, options])
这些函数可分为两类,第一类是显示信息,用户需要点击OK。
from tkinter import *
from tkinter import messagebox
root = Tk()
messagebox.showwarning('warning','something unexpected')
messagebox.showinfo('information','something informative')
messagebox.showerror('error','something wrong')
root.mainloop()
第二类是询问,用户需要选择。
from tkinter import *
from tkinter import messagebox
root = Tk()
messagebox.askquestion()
messagebox.askokcancel()
messagebox.askretrycancel()
messagebox.askyesnocancel()
messagebox.askyesno()
root.mainloop()