Article Directory
-
-
-
-
- Exercise 1: Use of canvas
- Exercise 2: Practice three layout managers
- Exercise 3: Mouse event and keyboard event usage
- Exercise 4: lambda expressions to pass parameters
- Exercise 5: Multiple event binding methods
- Exercise 6: OptionMenu selection items
- Exercise 7: Scale moving the slider
- Exercise 8: Method test of dynamic font adjustment
- Exercise 9: Basic usage of color selection box
- Exercise 10: Basic usage of the file dialog
- Exercise 11: Simple input dialog
- Exercise 12: General message box
-
-
-
Exercise 1: Use of canvas
Test to draw straight lines, circles, semicircles, triangles and other images, or insert pictures
from tkinter import *
from tkinter import messagebox
#定义坐标位置
lineposition = ((30,50),(300,100),(20,50))
rectposition = ((50,50),(100,100))
ovalposition = ((150,50),(250,150))
arcposition = ((350,50),(250,150))
coorposition = ((100,100),(50,150),(150,150),(80,200),(120,200))
class Application(Frame):
def __init__(self,master=None):
super().__init__(master)
self.master = master
self.pack()
self.TestCanvas()
def TestCanvas(self):
canvas = Canvas(self, width = 500, height = 350)
canvas["bg"] = "blue"
canvas.pack()
#画直线
line = canvas.create_line(lineposition)
#画矩形
rect = canvas.create_rectangle(rectposition)
#画圆形
oval = canvas.create_oval(ovalposition)
#画四分一圆形
arc = canvas.create_arc(arcposition)
#画多边形
coor1 = canvas.create_polygon(coorposition)
coor2 = canvas.create_polygon(200,200,400,200,300,300)
#插入图画
global photo
photo = PhotoImage(file="photo/pngphoto/小黄人.png")
canvas.create_image(380,250,image=photo)
Clichong = Tk()
Clichong.geometry("600x400+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()
Exercise 2: Practice three layout managers
tkinter provides three types of managers: pack, grid, and place.
1.grid layout manager
grid table layout, using table structure to organize components. The position of sub-components is determined by row and column cells, and can span rows and columns to achieve complex layouts.
Test 1: Write a simple login interface
#使用grid布局
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master=None):
super().__init__(master)
self.master = master
self.pack()
self.Mytest()
def Mytest(self):
lb1 = Label(self,text="用户名:")
lb1.grid(row=0,column=0)
et1 = Entry(self,show="*")
et1.grid(row=0,column=1)
bt1 = Button(self,width=5,height=1,text="登录")
bt1.grid(row=1,column=1,sticky="es") # sticky控制好方位
Clichong = Tk()
Clichong.geometry("600x400+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()
Test 2: Write a simple layout of a calculator
#使用grid布局
from tkinter import *
from tkinter import messagebox
#定义好按钮上面text内容
btnumber = (("MC","M+","M-","MR"),\
("C","±","+","*"),\
(7,8,9,"-"),\
(4,5,6,"+"),\
(1,2,3,"="),\
(0,"."))
class Application(Frame):
def __init__(self,master=None):
super().__init__(master)
self.master = master
self.pack()
self.Mytest()
def Mytest(self):
Entry(self).grid(row=0,column=0,columnspan=4,pady=10,sticky="nsew")
print((list(enumerate(btnumber))))
for rows,datainfo in enumerate(btnumber):
for nums,singledatainfo in enumerate(datainfo):
#对于等号与点号需要做特殊在处理
if singledatainfo == "=":
Button(self,text=singledatainfo).grid(row=rows+1,column=nums,rowspan=2,sticky="nsew")
elif singledatainfo == ".":
Button(self, text=singledatainfo).grid(row=rows + 1, column=nums, columnspan=2, sticky="nsew")
else:
Button(self,text=singledatainfo).grid(row=rows+1,column=nums,sticky="nsew")
Clichong = Tk()
Clichong.geometry("140x220+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()
2.pack layout manager
Pack adds the child components to the parent component in the order of component creation, and arranges them naturally in a vertical or horizontal direction. If you do not specify any options, the default is to add components vertically from top to bottom in the parent component.
Test: Making piano key layout
#使用grid布局
from tkinter import *
from tkinter import messagebox
btstring = ("伴奏1","伴奏2","伴奏3","旋律1","旋律2")
Clichong = Tk()
Clichong.geometry("500x240+300+300")
Clichong.title("钢琴键")
# 思路,这里我们需要定义两个pack,一个放按钮,另外一个放置钢琴键。而这两个pack都在Clichong这个背景上面
# 放置按钮
pianobt = Frame(Clichong)
pianobt.pack(pady=15)
for bttext in btstring:
Button(pianobt,text=bttext,width=5,height=1).pack(side="left",padx=10)
# 放置钢琴键
pianoky = Frame(Clichong)
pianoky.pack(pady=10)
for btpiano in range(0,11):
Button(pianoky,width=5,height=10,bg="black" if btpiano%2==0 else "white").pack(side="left")
# 一定要设置循环,不然无法实现
Clichong.mainloop()
3.place layout manager
The place layout manager can precisely control the position of components through coordinates, which is suitable for some scenarios with more flexible layouts.
Test 1: Simply test the place component
# 测试place布局
from tkinter import *
Clichong = Tk()
Clichong.geometry("400x200+400+300")
Clichong["bg"] = "blue"
# 放置一个黄色的方框
fm1 = Frame(Clichong,bg="yellow",width=100,height=100)
fm1.place(x=30,y=35)
# 放置一个绿色的方框
fm2 = Frame(Clichong,bg="green",width=100,height=100)
fm2.place(x=270,y=35)
# 放置三个按钮
Button(fm1,text="bt1",bg="green").place(relx=0.3,rely=0.7)
Button(fm2,text="bt2",bg="yellow").place(relx=0.7,rely=0.3)
Button(Clichong,text="bt",bg="white").place(width=60,height=30,relx=0.45,rely=0.4)
Clichong.mainloop()
Test 2: Playing card game operation settings
# 扑克出牌
from tkinter import *
Clichong = Tk()
Clichong.geometry("600x400+300+300")
# 图像处理
myphoto = [PhotoImage(file="photo/puke/puke"+str(pukenumber+1)+".gif")for pukenumber in range(10)]
mypuke = [Label(Clichong,image=myphoto[i])for i in range(10)]
# 放置扑克牌
for i in range(10):
mypuke[i].place(x=50+40*i,y=130)
# 触发事件的操作函数
def pukeoutfunction(event):
print(event.widget.winfo_geometry()) # 打印geometry信息
print(event.widget.winfo_y()) # 打印y坐标
# 如果y坐标在底下,则出牌
if event.widget.winfo_y() == 130:
event.widget.place(y=80)
# 如果y坐标已出,则收牌
else:
event.widget.place(y=130)
# 对label事件点击的绑定出牌操作
mypuke[1].bind_class("Label","<Button-1>",pukeoutfunction)
Clichong.mainloop()
Initial state
Click any card,
click again to take it back
Exercise 3: Mouse event and keyboard event usage
The entire life cycle of a GUI application is in an event loop. It waits for the occurrence of the event and handles it accordingly. Tkinter provides a mechanism to handle related events. Handle functions can be bound to various events of each control. widget.bind(event, handler) If a related event occurs, the handler function will be triggered, and the event object event will be passed to the handler function.
Mouse and keyboard events:
Common attributes of event objects:
from tkinter import *
Clichong = Tk()
Clichong.geometry("600x400+300+300")
bt1 = Button(Clichong,bg="blue",text="bt1").place(x=50,y=120,width=50,height=20)
#lb1 = Label(Clichong,bg="pink").place(x=300,y=100,width=100,height=30)
c1 = Canvas(Clichong,width=50,height=50,bg="pink")
c1.place(x=50,y=20)
c2 = Canvas(Clichong,width=200,height=200,bg="orange")
c2.place(x=120,y=20)
# 打印相关信息,测试event 对象常用属性
def mouseTest(event):
print("鼠标左键单击位置(相对于父容器):{0},{1}".format(event.x,event.y))
print("鼠标左键单击位置(相对于屏幕):{0},{1}".format(event.x_root,event.y_root))
print("事件绑定的组件:{0}".format(event.widget))
print("event.type:{0}".format(event.type))
print("event.width:{0},event.height:{1}".format(event.width,event.height))
penfont=2 # 设置画笔的粗细
def mouseDrag(event):
# 不断的画圆,看上去像是画笔,但是event.x+var加大了就知道是个圆
c2.create_oval(event.x, event.y, event.x+penfont, event.y+penfont)
# 键盘任意按键触发事件,打印按下的键盘键,测试event 对象常用属性
def keyboardTest(event):
print("按键keycode:{0}\n按键char:{1}\n按键keysym:{2}\n".format(event.keycode,event.char,event.keysym))
# 按键A/a测试
def keyboardTest_A(event):
print("your press A/a")
def keyboardTest_DoubleA(event):
print("your press A/a twice times")
def keyboardTest_CtrlA(event):
print("your press ctrl+A/a")
# 进入c2组件区域测试
def enterTest(event):
print("event_x:{0},event_y:{1}".format(event.x_root,event.y_root))
# 点击触发事件
c1.bind("<Button-1>",mouseTest)
# 拖动触发事件
c2.bind("<B1-Motion>",mouseDrag)
# 键盘触发事件,一个个测试
# 一般来说,键盘的按键都是绑定主界面
Clichong.bind("<KeyPress>",keyboardTest)
Clichong.bind("<KeyPress-a>",keyboardTest_A)
Clichong.bind("<KeyPress-A>",keyboardTest_A)
Clichong.bind("<Double-KeyPress-a>",keyboardTest_DoubleA)
Clichong.bind("<Control-KeyPress-a>",keyboardTest_CtrlA)
# 鼠标指针进入某一组件区域测试
c2.bind("<Enter>",enterTest)
Clichong.mainloop()
Exercise 4: lambda expressions to pass parameters
The lambda expression defines an anonymous function, which is only suitable for simple input parameters and simple calculations to return results, which is not suitable for complex functions. The anonymous function defined by lambda also has input and output, but it has no name.
The syntax format is as follows: lambda parameter value list: expression
- The parameter value list is the input.
- The structure of the expression calculation is the output.
from tkinter import *
Clichong = Tk()
Clichong.geometry("270x100")
def MyTest(str1,str2):
print(str1,"make friend with",str2)
# 使用lambda关键字可以实现传递多个参数操作
Button(Clichong,text="bt1",command=lambda :MyTest("Clichong","Lawrence")).pack()
t1 = lambda x,y:x**y
t2 = lambda :MyTest("A","B")
print("t1(2,3):",t1(2,3),"\n","MyTest(A,B)",t2)
Clichong.mainloop()
Exercise 5: Multiple event binding methods
- Binding of component objects
- Binding through the command attribute (suitable for simple and no need to obtain the event object)
Button(root,text=”login”,command=login) - Binding through the bind() method (suitable for obtaining event objects)
c1 = Canvas(); c1.bind("",drawLine)
ps:
Binding in command mode, you cannot directly obtain the event object" "
Binding in bind mode, you can obtain the event object" "
- Binding of component classes
Call the bind_class function of the object to bind all the components of the component class to events: w.bind_class("Widget","event",eventhanler) For
example: btn01.bind_class("Button","",func)
Refer to the previous small example of playing cards:
from tkinter import *
Clichong = Tk()
Clichong.geometry("600x400+300+300")
myphoto = [PhotoImage(file="photo/puke/puke"+str(pukenumber+1)+".gif")for pukenumber in range(10)]
mypuke = [Label(Clichong,image=myphoto[i])for i in range(10)]
for i in range(10):
mypuke[i].place(x=50+40*i,y=130)
def pukeoutfunction(event):
print(event.widget.winfo_geometry())
print(event.widget.winfo_y())
if event.widget.winfo_y() == 130:
event.widget.place(y=80)
else:
event.widget.place(y=130)
# 对label事件点击的绑定出牌操作,bind_class直接绑定label这整一类
mypuke[1].bind_class("Label","<Button-1>",pukeoutfunction)
Clichong.mainloop()
Exercise 6: OptionMenu selection items
Introduction:
class OptionMenu(Menubutton):
"""OptionMenu which allows the user to select a value from a menu."""
def __init__(self, master, variable, value, *values, **kwargs):
"""Construct an optionmenu widget with the parent MASTER, with
the resource textvariable set to VARIABLE, the initially selected
value VALUE, the other menu values VALUES and an additional
keyword argument command."""
kw = {"borderwidth": 2, "textvariable": variable,
"indicatoron": 1, "relief": RAISED, "anchor": "c",
"highlightthickness": 2}
test:
from tkinter import *
Clichong = Tk()
Clichong.geometry("400x300+300+300")
# 设置变量,方便回去选择项获取的内容,与其他空间类型操作
opmfirstvar = StringVar()
opmfirstvar.set("蔬菜面")
opm1 = OptionMenu(Clichong,opmfirstvar,"蔬菜面","兰州拉面","豚骨拉面","地狱拉面")
opm1.place(x=50,y=30,width=120,height=40)
def ShowLabel():
print(opmfirstvar.get())
bt1 = Button(Clichong,width=3,command=ShowLabel).place(x=50,y=100)
Clichong.mainloop()
Exercise 7: Scale moving the slider
Introduction:
class Scale(Widget):
"""Scale widget which can display a numerical scale."""
def __init__(self, master=None, cnf={}, **kw):
"""Construct a scale widget with the parent MASTER.
Valid resource names: activebackground, background, bigincrement, bd,
bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
highlightbackground, highlightcolor, highlightthickness, label,
length, orient, relief, repeatdelay, repeatinterval, resolution,
showvalue, sliderlength, sliderrelief, state, takefocus,
tickinterval, to, troughcolor, variable, width."""
Widget.__init__(self, master, 'scale', cnf, kw)
test:
from tkinter import *
Clichong = Tk()
Clichong.geometry("400x300")
lb1 = Label(Clichong,text="Clichong",width=10,height=2,font=("宋体",20))
lb1.pack()
# label不支持以下的操作:TypeError: 'NoneType' object does not support item assignment
# lb1["font"] = ("宋体",20)
# 通过函数传递当前值
def mytest(value):
print(value)
newFont = ("黑体", value)
lb1.config(font=newFont)
sc1 = Scale(Clichong,from_=10,to=100,length=300,width=30,command=mytest)
# 组件Scale可以支持如下操作
sc1["orient"] = HORIZONTAL
sc1.pack()
Clichong.mainloop()
Before
adjustment: After adjustment:
Exercise 8: Method test of dynamic font adjustment
Based on the failure of the above font adjustment, this part will be debugged again
from tkinter import *
Clichong = Tk()
Clichong.geometry("400x300")
lb1 = Label(Clichong,text="Clichong",width=10,height=2,font=("宋体",20))
lb1.pack()
# 经测试,以下两种动态调整字体的方法都可以
def func1():
lb1["font"] = ("黑体", 40)
def func2():
lb1.config(font=("黑体",30))
bt1 = Button(Clichong,command=func1).pack(side="left")
bt2 = Button(Clichong,command=func2).pack(side="left")
Clichong.mainloop()
Button 1:
Button 2:
Exercise 9: Basic usage of color selection box
The color selection box can help us set the background color, foreground color, pen color, font color and so on.
# 颜色选择框
from tkinter import *
from tkinter.colorchooser import *
Clichong = Tk()
Clichong.geometry("400x300")
def mytest():
# 设置初始选择的颜色是绿色,颜色框标题是"My color"
cr = askcolor(color="green",title="My color")
# 得出的结果是((128.5, 255.99609375, 255.99609375), '#80ffff')
print(cr)
# 设置背景颜色,以下两种方法均可
Clichong["bg"] = cr[1]
Clichong.config(bg = cr[1])
Button(Clichong,text="选择背景色",command=mytest).pack()
Clichong.mainloop()
Bring up the color selection box:
click OK to change the background color
Exercise 10: Basic usage of the file dialog
The file dialog box helps us realize the visual operation catalog and operation files. Finally, pass the file and directory information into the program. The file dialog contains the following commonly used functions:
The common values of the named parameter options are as follows:
Test 1: Return the selected file name
# 文件选择框
from tkinter import *
from tkinter.filedialog import *
Clichong = Tk()
Clichong.geometry("400x300")
def mytest():
askfile = askopenfilename(title="My File")
lb1["text"] = askfile
Button(Clichong,command=mytest).pack()
lb1 = Label(Clichong,width=40,height=3,bg="green")
lb1.pack()
Clichong.mainloop()
Click the button to pop up the file selection box: After
selection, the file name will be displayed on the label
Test 2: Open the specified txt file and read the content of the file to the window
# 文件选择框
from tkinter import *
from tkinter.filedialog import *
Clichong = Tk()
Clichong.geometry("400x300")
def mytest1():
askfile = askopenfilename(title="My File")
lb1["text"] = askfile
def mytest2():
with askopenfile(title="File") as fd:
lb2.config(text=fd.read())
Button(Clichong,command=mytest1).pack(side="left")
Button(Clichong,command=mytest2).pack(side="left")
lb1 = Label(Clichong,width=40,height=3,bg="pink")
lb1.pack()
lb2 = Label(Clichong,width=40,height=10,bg="blue")
lb2.pack()
Clichong.mainloop()
Test button 1:
Output file path King
Test button 2:
Output file content
Exercise 11: Simple input dialog
simpledialog (simple dialog box) contains the following commonly used functions: among the
parameters, title represents the window title; prompt is the prompt message; the named parameter kw is various options: initialvalue (initial value), minvalue (minimum value), maxvalue (maximum value).
# 颜色选择框
from tkinter import *
from tkinter.simpledialog import *
Clichong = Tk()
Clichong.geometry("400x300")
lb1 = Label(Clichong,width=40,height=3,bg= "green")
lb1.pack()
# Button(Clichong,text="选择背景色",command=mytest).pack()
getstr = askinteger(title="about age",prompt="input your age",initialvalue=0,minvalue=0,maxvalue=100)
lb1.config(text=getstr)
Clichong.mainloop()
More than 100 will warn:
Exercise 12: General message box
The messagebox (general message box) is used for simple interaction with the user. The user clicks OK and Cancel. The common functions of messagebox are listed as follows:
test code:
from tkinter import *
from tkinter.messagebox import *
Clichong = Tk()
Clichong.geometry("400x300")
# box1 = askokcancel(Clichong,"你是男的女的")
# box2 = askquestion(title="问题1",message="你是男的女的")
# box3 = askyesnocancel(title="问题1",message="你是男的女的")
# box4 = showinfo(title="问题1",message="你是男的女的")
box5 = showerror(title="问题1",message="你是男的女的")
Clichong.mainloop()
- ttk submodule control
The components we learned earlier are the components under the tkinter module, and the overall style is older and uglier. In order to make up for this shortcoming, the ttk component was introduced. ttk components are more beautiful and more powerful. Use Combobox to replace the original Listbox, and add LabeledScale (labeled Scale), Notebook (multi-document window), Progressbar (progress bar), Treeview (number) and other components.
There is not much
difference between using ttk components and ordinary Tkinter components , as long as you import the ttk module.