# 今天开始使用博客记录我的python学习部分笔记,从当前进度第9章开始,因教材用中文这里也用中文

2. 开始使用Tkinter

1 # Program 9.1
 2 from tkinter import *
 3 
 4 window = Tk()
 5 label = Label(window, text = "Welcome to Python")
 6 button = Button(window, text = "Click me")
 7 label.pack()
 8 button.pack()
 9 
10 window.mainloop()

4)Tk() 创建一个窗口实例,window为该实例

5-6) Label与Button是Python Tkinter的小构件类,其第一个参数为父容器(window)

7-8) pack()使用一个包管理器将label与button放在容器内

10)window.mainloop() 创建一个时间循环,用来与用户进行单击鼠标、敲击键盘等交互(Tkinter程序设计是事件驱动的)

3. 处理事件

1 # Program 9.2
 2 from tkinter import *
 3 
 4 def processOK():
 5     print("OK button is clicked")
 6 
 7 def processCancel():
 8     print("Cancel button is clicked")
 9 
10 window = Tk()
11 btOK = Button(window, text = "OK", fg = "red", command = processOK)
12 btCancel = Button(window, text = "Cancel", bg = "yellow", command = processCancel)
13 btOK.pack()
14 btCancel.pack()
15 
16 window.mainloop()

11-12) Button(window, text, fg, bg, command) 其中window为父容器,text为该按钮显示的字符串,fg为前景颜色(foreground color),bg为背景颜色(background color),command为回调函数,即点击此按钮时调用的函数名称(此处为processOK与processCancel)

1 # Program 9.3
 2 from tkinter import *
 3 
 4 class ProcessButtonEvent:
 5     def __init__(self):
 6         window = Tk()
 7         btOK = Button(window, text = "OK", fg = "red", command = self.processOK)
 8         btCancel = Button(window, text = "Cancel", bg = "yellow", command = self.processCancel)
 9         btOK.pack()
10         btCancel.pack()
11         window.mainloop()
12 
13     def processOK(self):
14         print("OK button is clicked")
15 
16     def processCancel(self):
17         print("Cancel button is clicked")
18 
19 ProcessButtonEvent()

此程序用__init__方法定义一个类,并定义方法self.processOK()与self.processCancel()。定义成类可以重复使用这个类,且这些方法可以访问类中的数据域

4.小构件类

创建一个小构件对象时,可以指定前景色、背景色、字体和光标风格等。

创建后想要修改小构件对象的属性,使用如下语法:

bt = Button(window, text = "Show", bg = "white")
bt["text"] = "Hide"
bt["bg"] = "red"
bt["justify"] = LEFT # make things left-leaning

下面是一个使用若干小构件类的程序:

1 # Program 9.4
 2 from tkinter import *
 3 
 4 class WidgetsDemo:
 5     def __init__(self):
 6         window = Tk()
 7         window.title("Widgets Demo")
 8 
 9         frame1 = Frame(window)
10         frame1.pack()
11         self.v1 = IntVar()
12         cbtBold = Checkbutton(frame1, text = "Bold", variable = self.v1, command = self.processCheckButton)
13         
14         self.v2 = IntVar()
15         rbRed = Radiobutton(frame1, text = "Red", bg = "red", variable = self.v2, value = 1, command = self.processRadioButton)
16         rbYellow = Radiobutton(frame1, text = "Yellow", bg = "yellow", variable = self.v2, value = 2, command = self.processRadioButton)
17 
18         cbtBold.grid(row = 1, column = 1)
19         rbRed.grid(row = 1, column = 2)
20         rbYellow.grid(row = 1, column = 3)
21 
22         frame2 = Frame(window)
23         frame2.pack()
24         
25         label = Label(frame2, text = "Enter your name: ")
26         self.name = StringVar()
27         entryName = Entry(frame2, textvariable = self.name)
28         btGetName = Button(frame2, text = "Get Name", command = self.processButton)
29         message = Message(frame2, text = "It is a widgets demo")
30 
31         label.grid(row = 1, column = 1)
32         entryName.grid(row = 1, column = 2)
33         btGetName.grid(row = 1, column = 3)
34         message.grid(row = 1, column = 4)
35 
36         text = Text(window)
37         text.pack()
38         text.insert(END, "Tip\nThe best way to learn Tkinter is to read ")
39         text.insert(END, "these carefully designed examples and use them ")
40         text.insert(END, "to create your applications.")
41 
42         window.mainloop()
43 
44     def processCheckButton(self):
45         print("check button is " + ("checked" if self.v1.get() == 1 else "Unchecked"))
46 
47     def processRadioButton(self):
48         print(("Red" if self.v2.get() == 1 else "Yellow") + " is selected ")
49 
50     def processButton(self):
51         print("Your name is " + self.name.get())
52 
53 WidgetsDemo()

7)window.title("...")设置窗口标题

9、22) Frame()创建框架实例,作为小控件的父容器

11) IntVar()、DoubleVar()、StringVar()是Tkinter模块中定义的类,代表一个整形、浮点型与字符串变量,可将这些变量与小控件绑定

12) Checkbutton(frame, text, variable, command) 创建一个单击复选按钮在0与1之间切换,其与变量variable(此处为v1这个IntVar)绑定,当单选按钮被选中时v1=1,否则v1=0

14-16) Radiobutton(frame, text, bg, fg, variable, value, command) 创建一个单选按钮,与variable绑定,当此按钮被勾选时将variable设为value

18-20) bt.grid(row = x, column = y)网络几何管理器将若干处在同一frame中的小控件按指定行数列数排列

25) Label(frame, text)创建一个标签

27) Entry(frame, textvariable)创建一个输入域,其文本内容与textvariable绑定,声明textvariable必须是StringVar()的实例

28) btGetName在被单机时调用self.processButton(),访问数据域self.name并输出

29) Message(frame, text)可将文本自动调整至多行显示(类似标签)

36-40) Text()创建一个Text小构件,使用insert方法插入文本,END代表当前内容结尾

 

1 // Program 9.5
 2 from tkinter import *
 3 
 4 class ChangeLabelDemo:
 5     def __init__(self):
 6         window = Tk()
 7         window.title("Change Label Demo")
 8 
 9         frame1 = Frame(window)
10         frame1.pack()
11         self.lbl = Label(frame1, text = "Programming is fun")
12         self.lbl.pack()
13 
14         frame2 = Frame(window)
15         frame2.pack()
16         label = Label(frame2, text = "Enter text: ")
17         self.msg = StringVar()
18         entry = Entry(frame2, textvariable = self.msg)
19         btChangeText = Button(frame2, text = "Change Text", command = self.processButton)
20         self.v1 = StringVar()
21         rbRed = Radiobutton(frame2, text = "Red", bg = "red", variable = self.v1, value = 'R', command = self.processRadiobutton)
22         rbYellow = Radiobutton(frame2, text = "Yellow", bg = "yellow", variable = self.v1, value = 'Y', command = self.processRadiobutton)
23 
24         label.grid(row = 1, column = 1)
25         entry.grid(row = 1, column = 2)
26         btChangeText.grid(row = 1, column = 3)
27         rbRed.grid(row = 1, column = 4)
28         rbYellow.grid(row = 1, column = 5)
29 
30         window.mainloop()
31 
32     def processRadiobutton(self):
33         if self.v1.get() == 'R':
34             self.lbl["fg"] = "red"
35         elif self.v1.get() == 'Y':
36             self.lbl["fg"] = "yellow"
37 
38     def processButton(self):
39         self.lbl["text"] = self.msg.get()
40 
41 ChangeLabelDemo()

 

33、35、39)方法在访问类数据域时,需要self.msg.get(),不要忘记self与get(),因msg等都是类的私有数据类型,需要用get()访问

34、36、39)用到了更改小控件参数的方法thing["text"] = "...",方框中填参数名称的字符串,等号后是更改为的内容

11)由于后面的方法中需要访问此标签,故定义为self.lbl = Label(...),使此标签lbl称为类的数据域中的一员,赋予后面方法访问的可能

5. 画布

1 // Program 9.6
 2 from tkinter import *
 3 
 4 class CanvasDemo:
 5     def __init__(self):
 6         window = Tk()
 7         window.title("Canvas Demo")
 8 
 9         self.canvas = Canvas(window, width = 200, height = 100, bg = "white")
10         self.canvas.pack()
11 
12         frame = Frame(window)
13         frame.pack()
14         btRectangle = Button(frame, text = "Rectangle", command = self.displayRect)
15         btOval = Button(frame, text = "Oval", command = self.displayOval)
16         btArc = Button(frame, text = "Arc", command = self.displayArc)
17         btPolygon = Button(frame, text = "Polygon", command = self.displayPolygon)
18         btLine = Button(frame, text = "Line", command = self.displayLine)
19         btString = Button(frame, text = "String", command = self.displayString)
20         btClear = Button(frame, text = "Clear", command = self.clearCanvas)
21 
22         btRectangle.grid(row = 1, column = 1)
23         btOval.grid(row = 1, column = 2)
24         btArc.grid(row = 1, column = 3)
25         btPolygon.grid(row = 1, column = 4)
26         btLine.grid(row = 1, column = 5)
27         btString.grid(row = 1, column = 6)
28         btClear.grid(row = 1, column = 7)
29 
30         window.mainloop()
31 
32     def displayRect(self):
33         self.canvas.create_rectangle(10, 10, 190, 90, tags = "rect")
34 
35     def displayOval(self):
36         self.canvas.create_oval(10, 10, 190, 90, fill = "red", tags = "oval")
37 
38     def displayArc(self):
39         self.canvas.create_arc(10, 10, 190, 90, start = 0, extent = 90, width = 8, fill = "red", tags = "arc")
40 
41     def displayPolygon(self):
42         self.canvas.create_polygon(10, 10, 190, 90, 30, 50, tags = "polygon")
43 
44     def displayLine(self):
45         self.canvas.create_line(10, 10, 190, 90, fill = "red", tags = "line")
46         self.canvas.create_line(10, 90, 190, 10, width = 9, arrow = "last", activefill = "blue", tags = "line")
47 
48     def displayString(self):
49         self.canvas.create_text(60, 40, text = "Hi, I am a string", font = "Times 10 bold underline", tags = "string")
50 
51     def clearCanvas(self):
52         self.canvas.delete("rect", "oval", "arc", "polygon", "line", "string")
53 
54 CanvasDemo()

9)再次重复,声明self.canvas=Canvas(...)是因为后续函数需要访问该画布,故将其设为类的数据域中的成员

32-49) self.canvas.create_***(...)是Canvas类的方法,用于绘制各种几何图形,具体公式为:

 

canvas.create_rectangle(x1, y1, x2, y2)
canvas.create_oval(x1, y1, x2, y2) # a rectangle that corners the oval
canvas.create_arc(x1, y1, x2, y2, start, extent) #corner start angle and range
canvas.create_polygon(x1, y1, x2, y2, x3, y3) # points for polygon
canvas.create_line(x1, y1, x2, y2) # two points for line
canvas.create_text(x, y, text) # display text string at (x, y)

 

46) canvas.create_line(..., activefill)中的activefill参数是当鼠标经过该直线时直线变更为的显示颜色

52) canvas.delete("..","..")删除引号中的图形,对应有"oval"、"rectangle"等等