6.几何管理器
Tkinter中的几何管理器分为:网格管理器、包管理器与位置管理器(最好不要对同一容器中的小构件使用多种管理器)
①网格管理器:将各个空间分布在看不见的网格中
1 # Program 9.7 2 from tkinter import * 3 4 class GridManagerDemo: 5 window = Tk() 6 window.title("Grid Manager Demo") 7 8 message = Message(window, text = "This Message widget occupies three rows and two columns") 9 message.grid(row = 1, column = 1, rowspan = 3, columnspan = 2) 10 Label(window, text = "First Name:").grid(row = 1, column = 3) 11 Entry(window).grid(row = 1, column = 4, padx = 5, pady = 5) 12 Label(window, text = "Last Name:").grid(row = 2, column = 3) 13 Entry(window).grid(row = 2, column = 4) 14 Button(window, text = "Get Name").grid(row = 3, column = 4, padx = 5, pady = 5, sticky = E) 15 16 window.mainloop() 17 18 GridManagerDemo()
9) rowspan与columnspan将message放置在多行多列中
11、14) padx与pady填充单元格在水平与竖直位置上的可选空间,sticky = E使Button设置在单元格东边,E亦可以是W、S、N、NW、NE等组合
② 包管理器:将小构件一次一个放在另一个顶部或者一个挨着一个放置
1 # Program 9.8 2 from tkinter import * 3 4 class PackManagerDemo: 5 def __init__(self): 6 window = Tk() 7 window.title("Pack Manager Demo 1") 8 9 Label(window, text = "Blue", bg = "blue").pack() 10 Label(window, text = "Red", bg = "red").pack(fill = BOTH, expand = 1) 11 Label(window, text = "Green", bg = "green").pack(fill = BOTH) 12 13 window.mainloop() 14 15 PackManagerDemo()
10)fill参数选择X,Y或BOTH,代表小控件填充水平、竖直或两个方向上的空间
expand参数非零时,若父小构件比容纳所有打包小构件的所需空间都大,则将额外的空间分配给小构件
其运行结果如下(从上到下依次排布,有fill的会填充横纵向,有expand会被分配多余的空间):
1 # Program 9.9 2 from tkinter import * 3 4 class PackManagerDemoWithSide: 5 window = Tk() 6 window.title("Pack Manager Demo 2") 7 8 Label(window, text = "Blue", bg = "blue").pack(side = LEFT) 9 Label(window, text = "Red", bg = "red").pack(side = LEFT, fill = BOTH, expand = 1) 10 Label(window, text = "Green", bg = "green").pack(side = LEFT, fill = BOTH) 11 12 window.mainloop() 13 14 PackManagerDemoWithSide()
8-10) side = LEFT意味着靠左放,该选项可以是LEFT/RIGHT/TOP/BOTTOM
其运行结果如下(从左到右依次排布,有fill的会填充横纵向,有expand会被分配多余的空间):
③ 位置管理器:将小构件放在绝对位置上
1 # Program 9.10 2 from tkinter import * 3 4 class PlaceManagerDemo: 5 def __init__(self): 6 window = Tk() 7 window.title("Place Manager Demo") 8 9 Label(window, text = "Blue", bg = "blue").place(x = 20, y = 20) 10 Label(window, text = "Red", bg = "red").place(x = 50, y = 50) 11 Label(window, text = "Green", bg = "green").place(x = 80, y = 80) 12 13 window.mainloop() 14 15 PlaceManagerDemo()
9-11) 小控件.place(x, y)用位置管理器将小控件放在一定的绝对位置上
其运行结果如下:
注意:位置管理器不能兼容所有计算机,受分辨率的影响而影响,应尽量避免使用位置管理器
7. 实例研究:贷款计算器
开发一个GUI程序的主要步骤:
1)绘制轮廓图来设计用户界面
2)处理按钮等引发的事件
1 # Program 9.11 2 from tkinter import * 3 4 class LoanCalculator: 5 def __init__(self): 6 window = Tk() 7 window.title("Loan Calculator") 8 9 Label(window, text = "Annual Interest Rate").grid(row = 1, column = 1, sticky = W) 10 Label(window, text = "Number of Years").grid(row = 2, column = 1, sticky = W) 11 Label(window, text = "Loan Amount").grid(row = 3, column = 1, sticky = W) 12 Label(window, text = "Monthly Payment").grid(row = 4, column = 1, sticky = W) 13 Label(window, text = "Total Payment").grid(row = 5, column = 1, sticky = W) 14 15 self.annualInterestRateVar = StringVar() 16 Entry(window, textvariable = self.annualInterestRateVar, justify = RIGHT).grid(row = 1, column = 2) 17 self.numberOfYearsVar = StringVar() 18 Entry(window, textvariable = self.numberOfYearsVar, justify = RIGHT).grid(row = 2, column = 2) 19 self.loanAmountVar = StringVar() 20 Entry(window, textvariable = self.loanAmountVar, justify = RIGHT).grid(row = 3, column = 2) 21 22 self.monthlyPaymentVar = StringVar() 23 lblMonthlyPayment = Label(window, textvariable = self.monthlyPaymentVar).grid(row = 4, column = 2, sticky = E) 24 self.totalPaymentVar = StringVar() 25 lblTotalPayment = Label(window, textvariable = self.totalPaymentVar).grid(row = 5, column = 2, sticky = E) 26 27 btComputePayment = Button(window, text = "Compute payment", command = self.computePayment).grid(row = 6, column = 2, sticky = E) 28 29 window.mainloop() 30 31 def computePayment(self): 32 monthlyPayment = self.getMonthlyPayment(float(self.loanAmountVar.get()), float(self.annualInterestRateVar.get()) / 1200, int(self.numberOfYearsVar.get())) 33 self.monthlyPaymentVar.set(format(monthlyPayment, "10.2f")) 34 totalPayment = float(self.monthlyPaymentVar.get()) * 12 * int(self.numberOfYearsVar.get()) 35 self.totalPaymentVar.set(format(totalPayment, "10.2f")) 36 37 def getMonthlyPayment(self, loanAmount, monthlyInterestRate, numberOfYears): 38 monthlyPayment = loanAmount * monthlyInterestRate / (1 - 1 / (1 + monthlyInterestRate) ** (numberOfYears * 12)) 39 return monthlyPayment 40 41 LoanCalculator()
33、35) 可通过monthlyPaymentVar.set(...)的方式,更改与小构件绑定的变量值从而更改小构件的参数(如显示内容等)
16、23) Entry()与Label()皆使用textvariable的参数,不过Entry()中其指代用户输入的内容,Label()中指代标签显示的内容
many) 很多行当中都用到了Label(...).grid(...)的连写方式,即小构件无需另外变量储存,除非需要更改小构件参数(当然与其绑定的参数更改可以如上上行进行,但背景颜色、字体等参数仍然需要通过调用原小控件变量的方式进行更改,这种情况下就需要thing = Label(...).grid(...)的方式)
程序的运行结果如下:
8. 显示图像
# 鉴于书上程序实例中的图片文件没有获取,这里仅概述创建图像对象与显示的语法
创建:
myimage = PhotoImage(file = "yourpath.gif")
此时创建了一个图片路径为"yourpath.gif"的图片对象myimage。
与Button、Checkbutton、Radiobutton的互动:
Button(frame, image = myimage) Checkbutton(frame, image = myimage) Radiobutton(frame, image = myimage)
此举将创建包含myimage对象中的图像的各种按钮
与Canvas的互动:
canvas = Canvas(frame1)
canvas.create_image(width, height, image = myimage)
此举将创建一个背景内容为myimage对象所含图片的画布,事实上一张画布可以显示多个图像