Week10 - Graphical User Interfaces
本节我们来讲如何用Python做图形用户界面,之前写程序大家也发现在与用户做交互的过程中存在大小写的问题。虽然我们可以用改变大小写的函数方法(upper(),lower())的方法但是这样界面不够友好。
例 1 :
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mywindow.mainloop() #实时刷新窗口
运行结果:
解析:
- 代码前两行是在调用文件中的类和定义对象,这个下一节我们会详细讲解
- mainloop()函数是用来很快的循环刷新窗口。因为随着用户的不断操作,界面是在不断变化的。如果没有这行代码那窗口会一直维持初始状态。
接下来我们再往窗口中添加一些小部件(widgets )
例 2 :
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mylabel1 = Label(mywindow,text = "Hello",fg="red",bg="#ffff00")
mylabel1.grid(row=0,column=0) # 网格布局管理器
mylabel2 = Label(mywindow,text = "world")
mylabel2.grid(row=1,column=1)
mylabel3 = Label(mywindow,text = "!")
mylabel3.grid(row=2,column=2)
mywindow.mainloop() #实时刷新窗口
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mylabel1 = Label(mywindow,text = "Hello",fg="red",bg="#ffff00")
mylabel1.grid(row=0,column=0) # 网格布局管理器
mylabel2 = Label(mywindow,text = "world")
mylabel2.grid(row=3,column=2)
mylabel3 = Label(mywindow,text = "!")
mylabel3.grid(row=4,column=5)
mywindow.mainloop() #实时刷新窗口
运行相同结果:
解析:
- 这里grid()函数是用来布局的。其中的row和column后的参数不是表示在第几行(列)显示,而是表示一个层级关系将其有小到大排列后依次呈现。如果不填默认row=0,column自加,如下:
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mylabel1 = Label(mywindow,text = "Hello",fg="red",bg="#ffff00")
mylabel1.grid() # 网格布局管理器
mylabel2 = Label(mywindow,text = "world")
mylabel2.grid()
mylabel3 = Label(mywindow,text = "!")
mylabel3.grid()
mywindow.mainloop() #实时刷新窗口
运行结果:
如果将row都写成一样的话,不同的模块会相互遮掩,如下:
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mylabel1 = Label(mywindow,text = "Hello",fg="red",bg="#ffff00")
mylabel1.grid(row=0) # 网格布局管理器
mylabel2 = Label(mywindow,text = "world")
mylabel2.grid(row=0)
mylabel3 = Label(mywindow,text = "!")
mylabel3.grid(row=0)
mywindow.mainloop() #实时刷新窗口
运行结果:
例 2 :
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
def main():
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mylabel1 = Label(mywindow,text = "Please inter your name:")
mylabel1.grid(row=0,column=0) # 网格布局管理器
myentry = Entry(mywindow)
myentry.grid(row=0,column=1)
mywindow.mainloop() #实时刷新窗口
main()
运行结果:
例 3 :
from tkinter import * #调用tkinter文件中定义的所以类
mywindow = Tk() #定义mywindow是Tk()类的一个对象
def main():
mywindow.title('Hello world') #定义窗口标题
mywindow.geometry("500x500") #定义窗口大小
mylabel1 = Label(mywindow,text = "Please inter your name:")
mylabel1.grid(row=0,column=0) # 网格布局管理器
myentry = Entry(mywindow)
myentry.grid(row=0,column=1)
disbutton = Button(mywindow,text="SUBMIT")
disbutton.grid(row=1,column=0,columnspan=2)
mywindow.mainloop() #实时刷新窗口
main()
运行结果:
解析 :
这里columnspan是用来设置单元格横向跨越的列数,即控件占据的列数(宽度)
例 4:
from tkinter import *
Mywindow = Tk()
nameVar = StringVar() #定义nameVar是StringVar类的一个对象,这样是为了跟踪变量的值的变化,以保证值的变更随时可以显示在界面上
def displayGreet(): #定义输出问候的函数
print (f'Hello {nameVar.get()}, How are you!') #nameVar.get()用来实时获取nameVar里string类型变量
def main():
Mywindow.title("Button & Entry Demo")
myLable = Label(Mywindow, text="Please enter your name:")
myLable.grid(row=0, column=0)
myEntry = Entry(Mywindow, textvariable=nameVar) #textvariable显示文本自动更新,与StringVar等配合着用
myEntry.grid(row=0, column=1)
subButton = Button(Mywindow, text ="SUBMIT",command=displayGreet) #command用来在按钮中添加功能
subButton.grid(row=1,column=0, columnspan=2)
Mywindow.mainloop()
main()
运行结果:
例 5:
接下来我们让greet输出到我们定义的窗口里
from tkinter import *
Mywindow = Tk()
nameVar = StringVar()
greetVar = StringVar() #同上我们再定义一个greetVar类
def displayGreet():
greet=f'Hello {nameVar.get()}, How are you!'
greetVar.set(greet) #将greet的实时值传给greetVar
def main():
Mywindow.title("Button & Entry Demo")
myLable = Label(Mywindow, text="Please enter your name:")
myLable.grid(row=0, column=0)
myEntry = Entry(Mywindow, textvariable=nameVar)
myEntry.grid(row=0, column=1)
subButton = Button(Mywindow, text ="SUBMIT",command=displayGreet)
subButton.grid(row=1,column=0, columnspan=2)
# 为了使greet出现在窗口上我们定义一个label,text的内容为greetVar的实时值
greetlabel = Label(Mywindow, textvariable= greetVar )
greetlabel .grid(row=3, column=0)
Mywindow.mainloop()
main()
运行结果:
例 6:
from tkinter import *
mywindow = Tk()
var = StringVar(value='Red') #开始默认选择值为Red的Button
def select ():
color = var.get()
print ("Your selected " + color)
def main():
mywindow.title("Radio Button Demo")
# variable是用来保存var的值,value值刚开始默认为Red,下面三行代码又对value值进行了修改
R1 = Radiobutton(mywindow, text='Red', variable=var, value='Red', command=select)
R2 = Radiobutton(mywindow, text='Green', variable=var, value='Green', command=select)
R3 = Radiobutton(mywindow, text='Blue', variable=var, value='Blue', command=select)
R1.grid(sticky=W) #sticky选项去指定对齐方式,这里是左对齐的意思
R2.grid(sticky=W)
R3.grid(sticky=W)
mywindow.mainloop()
main()
运行结果:
练 :
from tkinter import *
mywindow = Tk()
def Greet():
print ("Greetings")
mywindow.title("A simple GUI")
mylabel = Label(mywindow,text="This is a simple GUI application!")
mylabel.grid(row=0,column=0,columnspan=2)
myButton1 = Button(mywindow,text="Greet",command=Greet)
myButton1.grid(row=1,column=0)
myButton2 = Button(mywindow,text="close",command=quit)
myButton2.grid(row=1,column=1)
mywindow.mainloop()
运行结果:
压轴:
from tkinter import *
import math
class TicketPriceCalc(Frame):
def __init__(self): #初始化方法,来初始化新创建对象的状态
Frame.__init__(self)
self.master.title("Welcome to Ticket Price Calculator!") #创建窗口
self.grid()
# 创建一个label和entry去提示输入买票的数量
self._numLabel = Label(self,text="Number of tickers")
self._numLabel.grid(row=0,column=0,sticky=W)
self._numVar = IntVar()
self._numEntry = Entry(self,width=7,textvariable = self._numVar)
self._numEntry.grid(row=0,column=1)
# 创建两个label,在窗口里显示总价格
self._nameLabel = Label(self,text = "Calculated ticket cost is :")
self._nameLabel.grid(row=4,column=0)
self._totalVar = DoubleVar()
self._totLabel = Label(self,textvariable =self._totalVar)
self._totLabel.grid(row=4,column=1)
# 创建单选按钮
self._var = DoubleVar()
self._R1 = Radiobutton(self,text="Tuesday",variable=self._var,value=12)
self._R2 = Radiobutton(self,text="Weekend",variable=self._var,value=20)
self._R3 = Radiobutton(self,text="Weekend other than Tuesday",variable=self._var,value=17.5)
# 设置单选按钮的布局为左对齐依次排列
self._R1.grid(row=1,column=0,sticky=W)
self._R2.grid(row=2,column=0,sticky=W)
self._R3.grid(row=3,column=0,sticky=W)
# 创建计算按钮,并设置其布局
self._combtn = Button(self,text="Compute",command=self._total)
self._combtn.grid(row=5,column=0)
# 定义计算总价的函数
def _total(self):
total = self._var.get()*self._numVar.get()
self._totalVar.set("${:.2f}".format(total))
def main():
TicketPriceCalc().mainloop()
main()
运行结果:
这里是用class类去写的,算是给下一节Design with classes 做一个引子吧。