复选框(Checkbutton)是为返回多个选项值的交互控件,通常并不直接触发函数的执行。该控件除具有共同属性外,还具有显示文本(text)、返回变量(variable)、选中返回值(onvalue)和未选中默认返回值(offvalue)等重要的属性。
返回变量variable=var通常可以预先逐项分别声明变量的类型var=IntVar()(默认)或var=StringVar(),在所调用的函数中方可分别用var.get()方法取得被选中实例的onvalue或offvalue值。
复选框实例通常还可分别利用select()、deselect()和toggle()方法对其进行选中、清除选中和反选操作。
利用复选框实现,单击“OK”按钮后,可以将选中结果显示在标签上,
方法1:在函数中用if-else分支实现多项显示。
- from tkinter import *
-
-
- def run():
- if (CheckVar1.get() == 0 and CheckVar2.get() == 0 and CheckVar3.get() == 0 and CheckVar4.get() == 0):
- s = "您没有选择任何爱好项目"
- else:
- s1 = "足球" if CheckVar1.get() == 1 else ""
- s2 = "篮球" if CheckVar2.get() == 1 else ""
- s3 = "游泳" if CheckVar3.get() == 1 else ""
- s4 = "骑行" if CheckVar4.get() == 1 else ""
- s = "您选择了%s%s%s%s" % (s1, s2, s3, s4)
- lb2.config(text=s)
-
-
- window = Tk()
- lb1 = Label(window, text="请选择您的爱好项目:")
- lb1.pack()
- CheckVar1 = IntVar()
- CheckVar2 = IntVar()
- CheckVar3 = IntVar()
- CheckVar4 = IntVar()
- ch1 = Checkbutton(window, text="足球", variable=CheckVar1, onvalue=1, offvalue=0)
- ch2 = Checkbutton(window, text="篮球", variable=CheckVar2, onvalue=1, offvalue=0)
- ch3 = Checkbutton(window, text="游泳", variable=CheckVar3, onvalue=1, offvalue=0)
- ch4 = Checkbutton(window, text="骑行", variable=CheckVar4, onvalue=1, offvalue=0)
- ch1.pack()
- ch2.pack()
- ch3.pack()
- ch4.pack()
- btn = Button(window, text="OK", command=run)
- btn.pack()
- lb2 = Label(window, text='')
- lb2.pack()
- window.mainloop()

方法2:利用列表和字典实现多项显示。
由于Python程序中没有其他语言的switch或case这样的枚举分支,当选项较多时,用if-else分支实现会较为烦琐,可充分利用Python特有的列表、字典等数据类型使程序更加简洁高效。本例中还添加了全选、反选和重置按钮:
- from tkinter import *
-
-
- def run():
- dic = {0: '', 1: '足球', 2: '篮球', 3: '游泳', 4: '骑行'}
- chknum = {CheckVar1.get(), CheckVar2.get(), CheckVar3.get(), CheckVar4.get()}
- s = ''
- for i in chknum:
- s += dic.get(i)
- if s == '':
- s = "您没有选择任何爱好项目"
- else:
- s = "您选择了" + s
- lb2.config(text=s)
-
-
- def all():
- ch1.select()
- ch2.select()
- ch3.select()
- ch4.select()
-
-
- def invert():
- ch1.toggle()
- ch2.toggle()
- ch3.toggle()
- ch4.toggle()
-
-
- def cancel():
- ch1.deselect()
- ch2.deselect()
- ch3.deselect()
- ch4.deselect()
-
-
- window = Tk()
- lb1 = Label(window, text="请选择您的爱好项目:")
- lb1.pack()
- CheckVar1 = IntVar()
- CheckVar2 = IntVar()
- CheckVar3 = IntVar()
- CheckVar4 = IntVar()
- ch1 = Checkbutton(window, text="足球", variable=CheckVar1, onvalue=1, offvalue=0)
- ch2 = Checkbutton(window, text="篮球", variable=CheckVar2, onvalue=2, offvalue=0)
- ch3 = Checkbutton(window, text="游泳", variable=CheckVar3, onvalue=3, offvalue=0)
- ch4 = Checkbutton(window, text="骑行", variable=CheckVar4, onvalue=4, offvalue=0)
- ch1.pack()
- ch2.pack()
- ch3.pack()
- ch4.pack()
- btninvert = Button(window, text="反选", command=invert)
- btninvert.pack(side=RIGHT)
- btnall = Button(window, text="全选", command=all)
- btnall.pack(side=RIGHT)
- btncancel = Button(window, text="重置", command=cancel)
- btncancel.pack()
- btn = Button(window, text="OK", command=run)
- btn.pack()
- lb2 = Label(window, text='')
- lb2.pack()
- window.mainloop()

列表框(Listbox)可供用户单选或多选所列条目以形成人机交互。列表框控件的主要方法:

执行自定义函数时,通常使用“实例名.curselection()”或“selected”来获取选中项的位置索引。
由于列表框实质上就是将Python的列表类型数据可视化呈现,在程序实现时,也可直接将相关列表数据进行操作,然后再通过列表框展示出来,而不必拘泥于可视化控件的方法。
实现列表框的初始化、添加、插入、修改、删除和清空操作:
- from tkinter import *
- import tkinter
-
-
- def ini():
- Lstbox1.delete(0, END)
- list_items = ["数学", "物理", "化学", "语文", "外语"]
- for item in list_items:
- Lstbox1.insert(END, item)
-
-
- def clear():
- Lstbox1.delete(0, END)
-
-
- def ins():
- if entry.get() != '':
- if Lstbox1.curselection() == ():
- Lstbox1.insert(Lstbox1.size(), entry.get())
- else:
- Lstbox1.insert(Lstbox1.curselection(), entry.get())
-
-
- def updt():
- if entry.get() != '' and Lstbox1.curselection() != ():
- selected = Lstbox1.curselection()[0]
- Lstbox1.delete(selected)
- Lstbox1.insert(selected, entry.get())
-
-
- def delt():
- if Lstbox1.curselection() != ():
- Lstbox1.delete(Lstbox1.curselection())
-
-
- window = Tk()
- window.title('列表框学习')
- window.geometry('320x240')
- frame1 = Frame(window, relief=RAISED)
- frame1.place(relx=0.0)
- frame2 = Frame(window, relief=GROOVE)
- frame2.place(relx=0.5)
- Lstbox1 = Listbox(frame1)
- Lstbox1.pack()
-
- entry = Entry(frame2)
- entry.pack()
-
- btn1 = Button(frame2, text="初始化", command=ini)
- btn1.pack(fill=X)
- btn2 = Button(frame2, text="添加", command=ins)
- btn2.pack(fill=X)
- btn3 = Button(frame2, text="插入", command=ins)
- # 添加和插入功能实质是一样的
- btn3.pack(fill=X)
- btn4 = Button(frame2, text="修改", command=updt)
- btn4.pack(fill=X)
- btn5 = Button(frame2, text="删除", command=delt)
- btn5.pack(fill=X)
- btn6 = Button(frame2, text="清空", command=clear)
- btn6.pack(fill=X)
- window.mainloop()

若不使用按钮,也可对列表控件实例绑定鼠标事件,触发自定义函数的执行,自定义函数应以event作为参数以获取鼠标的选中项目索引。之后还将学习“事件响应”。通常,绑定的鼠标事件是鼠标左键的释放(不是单击,释放时才选中列表框选项)。例如:
Lstbox1.bind('<ButtonRelease-1>',myfunc)
单击课程或学分的列表框均可联动实现选课,并将所选课程和学分追加呈现在文本框中:
- from tkinter import *
-
-
- def ini():
- list_items = ["数学", "物理", "化学", "语文", "外语"]
- for item in list_items:
- Lstbox1.insert(END, item)
-
- list_credits = [2.0, 2.5, 1.0, 1.5, 2.0]
- for item in list_credits:
- Lstbox2.insert(END, item)
-
-
- def slecurse1(event):
- s = '已选' + Lstbox1.get(Lstbox1.curselection()) + str(Lstbox2.get(Lstbox1.curselection())) + '学分\n'
- txt.insert(END, s)
-
-
- def slecurse2(event):
- s = '已选' + Lstbox1.get(Lstbox2.curselection()) + str(Lstbox2.get(Lstbox2.curselection())) + '学分\n'
- txt.insert(END, s)
-
-
- window = Tk()
- window.title('单击课程或学分均可选课')
- window.geometry('320x240')
- frame1 = Frame(window, relief=RAISED)
- frame1.place(relx=0.0)
- frame2 = Frame(window, relief=GROOVE)
- frame2.place(relx=0.3)
- frame3 = Frame(window, relief=RAISED)
- frame3.place(relx=0.6)
-
- Lstbox1 = Listbox(frame1)
- Lstbox1.bind('<ButtonRelease-1>', slecurse1)
- Lstbox1.pack()
- Lstbox2 = Listbox(frame2)
- Lstbox2.bind('<ButtonRelease-1>', slecurse2)
- Lstbox2.pack()
-
- txt = Text(frame3, height=14, width=18)
- txt.pack()
- ini()
- window.mainloop()

组合框(Combobox)实质上是带文本框的下拉列表框,其功能也是将Python的列表类型数据可视化呈现,并提供用户单选或多选所列条目以形成人机交互。在图形化界面设计时,由于其具有灵活的界面,因此往往比列表框更受喜爱。但该控件并不包含在tkinter的子模块ttk中。
如果要使用该控件,应先用from tkinter import ttk语句引用ttk子模块,然后创建组合框实例:
实例名=Combobox(根对象,[属性列表])
绑定变量var=tkinter.StringVar(),并设置实例属性textvariable=var,values=[列表...]。
组合框控件的常用方法有:获得所选中的选项值get()和获得所选中的选项索引current()。
若不使用按钮,也可对组合框控件实例绑定事件,触发自定义函数的执行,自定义函数应以event作为参数以获取所选中项目索引。通常,绑定的事件是组合框中某选项被选中(注意,事件的代码是用两个小于号和两个大于号作为界定符的)。例如:
comb1.bind('<<ComboboxSelected>>',myfunc)
实现四则运算计算器,将两个操作数分别填入两个文本框后,通过选择组合框中的算法触发运算:
- from tkinter import *
- from tkinter.ttk import *
-
-
- def calc(event):
- a = float(t1.get())
- b = float(t2.get())
- dic = {0: a + b, 1: a - b, 2: a * 3, 3: a / b}
- c = dic[comb.current()]
- lb1.config(text=str(c))
-
-
- window = Tk()
- window.title('四则运算')
- window.geometry('320x240')
-
- t1 = Entry(window)
- t1.place(relx=0.1, rely=0.1, relwidth=0.2, relheight=0.1)
- t2 = Entry(window)
- t2.place(relx=0.5, rely=0.1, relwidth=0.2, relheight=0.1)
- var = StringVar()
- comb = Combobox(window, textvariable=var, values=['加', '减', '乘', '除'])
- comb.place(relx=0.1, rely=0.5, relwidth=0.2)
- comb.bind('<<ComboboxSelected>>', calc)
- lb1 = Label(window, text='结果')
- lb1.place(relx=0.5, rely=0.7, relwidth=0.2, relheight=0.3)
- window.mainloop()

通常,大型软件设计分为程序编码设计和用户界面(User Interface,UI)设计两个部分,它们分属于不同团队。上述四则运算计算器也可用下面代码,运用面向对象程序设计的思想,实现界面设计与业务逻辑的相互独立。这里,Ui类负责程序界面的布局,而App类作为Ui的子类,完成运算处理。
- from tkinter import *
- from tkinter.ttk import *
-
-
- class Ui(Frame):
- """ 生成界面的类 """
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- self.master.title('四则运算')
- self.master.geometry('320x240')
- self.createWidgets()
-
- def createWidgets(self):
- self.top = self.winfo_toplevel()
- self.Text1 = Entry(self.top)
- self.Text1.place(relx=0.1, rely=0.1, relwidth=0.3, relheight=0.1)
- self.Text2 = Entry(self.top)
- self.Text2.place(relx=0.5, rely=0.1, relwidth=0.3, relheight=0.1)
- self.CombolList = ['加', '减', '乘', '除']
- self.CombolVar = StringVar(value='加')
- self.Combol = Combobox(self.top, textvariable=self.CombolVar, values=self.CombolList)
- self.Combol.place(relx=0.1, rely=0.5, relwidth=0.4)
- self.Combol.bind('<<ComboboxSelected>>', self.calc)
- self.Label1 = Label(self.top)
- self.Label1.place(relx=0.5, rely=0.6, relwidth=0.4, relheight=0.2)
-
-
- class App(Ui):
- """ 继承Ui,为Ui的子类,处理业务逻辑 """
-
- def __init__(self, master=None):
- Ui.__init__(self, master)
-
- def calc(self, event):
- a = float(self.Text1.get())
- b = float(self.Text2.get())
- dic = {0: a + b, 1: a - b, 2: a * b, 3: a / b}
- c = dic[self.Combol.current()]
- self.Label1.config(text=str(c))
-
-
- if __name__ == '__main__':
- top = Tk()
- gui = App(top) # 实例化
- gui.mainloop()
