tkinter简介
tkinter模块(“Tk接口”)是Scriptics的Tk GUI工具包的标准Python接口,支持在Unix平台、Windows系统和Macintosh系统上运行。因为它由很多小构件组成,当我们在设计一个GUI时,可以通过它丰富的构件库满足我们的需求。
项目概述
本项目基于tkinter模块,设计了一个简易调查问卷,问卷本身并无任何意义,其目的仅在于掌握如何使用tkinter中的小构件。因为本项目涵盖了tkinter的绝大多构件,故对于tkinter的学习有很大帮助。
项目设计
tkinter库的导入
因为tkinter是python3自带的库,所以不需要自己安装。导入到工程时,通过from tkinter import *。(注意:tkinter的首字母不能使用大写。)
构建项目类,将TK类实例化
class TkDemo():
def __init__(self):
master = Tk()
master.title('TK学习')
在Python中,类应该先实例化,然后再使用类!
创建菜单栏
# 创建菜单栏 (Menu)
menubar = Menu(master)
master.config(menu=menubar)
# 创建文件下拉菜单
filemenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="文件", menu=filemenu)
filemenu.add_command(label="新建···", command=self.newfile)
filemenu.add_command(label="打开···", command=self.openfile)
filemenu.add_command(label="保存", command=self.savefile)
filemenu.add_command(label="关闭填写", command=master.quit)
步骤:先创建菜单栏;再创建下拉菜单,并设置标题;再添加下拉菜单中的内容。(注意继承关系。)label指的是名称,command指的是命令,即点击后所执行的代码。
(此处只列举了一个下拉菜单)
创建文字栏
title = Label(master, text='这是一份无趣的调查问卷--建文大帝编',font='15', bg='white', fg='red')
title.pack()
文字栏的创建比较简单。这里重点解释一下tkinter中的几何管理器。
想象我们设计出来的GUI界面是一个容器,我们要做的就是往这个父容器里添加其他构件,即添加子容器。怎么管理子容器在父容器中的位置呢?就由几何管理器来操作。
1 .pack() 包管理器
包管理器比较死板,控制方式就像在一个固定容器里搭积木,它会按照小构件的打包顺序依次向下搭起,默认是从顶部开始往里放直到全部放置完毕。我们可以使用 fill, expand, side来设置积木在矩形洞中的状态。
fill选项告诉包管理器这个小构件(widget)想填充这整个空间,并指定填充方式。
展示如下:
对于expand:当值非0时,是告诉包管理器分配额外的空间给构件,当父容器足够包裹所有的子构件时,多于的扩展空间就会填充在构件之间
(大家请自行尝试,看看窗口放大效果会更明显。)
2 .grid(row=x, column=y) 网格管理器
网格管理器被誉为Tkinter中最灵活的几何管理器,也是最需要学习的一种管理器。它把子容器放在一个二维的表里面,父容器被分成很多行和列,并在行和列所组成的每个单元格里面可以容纳一个子容器。
(后续例子中会大量使用网格管理器,请多留意)
3 .place(relx=x, rely=y, anchor=CENTER) 位置管理器
位置管理器直接指定小部件在窗口中的x和y值来设置位置,但是它不能兼容所有的计算机,在不同分辨率的窗口上排列的位置可能会不同,所以我们尽量避免使用它。
问题一(包含输入框和按钮)
# 问题1放在frame1中 (Frame)
frame1 = Frame(master)
frame1.pack(fill=X)
# 问题
label1 = Label(frame1, text='1、您的花名: ')
label1.grid(row=1, column=0)
# 输入框 (Entry)
self.name = StringVar()
entryname = Entry(frame1, textvariable=self.name)
entryname.grid(row=1, column=1)
# 按钮 (Button)
getname = Button(frame1, text='点击确认', command=self.getname)
getname.grid(row=1, column=3)
将输入框中的内容作为项目类的一个属性,后续方便调用。
解释一下frame1的作用:创建一个frame框架,即创造一个新的父容器,是为了将每个问题内容有效的隔开。在这个父容器里放置子容器,能得到更好安排。
问题二(包含选择按钮)
# 问题2放在frame2中
frame2 = Frame(master)
frame2.pack(fill=X)
# 问题
label2 = Label(frame2, text='2、您的性别: ')
label2.grid(row=1, column=0)
# 选择按钮 (Radiobutton)
self.sex = StringVar()
sex_male = Radiobutton(frame2, text='男', fg='blue', variable=self.sex, value='男', command=self.getsex)
sex_male.grid(row=1, column=2)
sex_female = Radiobutton(frame2, text='女', fg='red', variable=self.sex, value='女', command=self.getsex)
sex_female.grid(row=1, column=4)
Radiobutton中的变量variable我们设置为self.sex,方便后续调用,其值就是value。
问题三(包含滑动条)
# 问题3放在frame3中
frame3 = Frame(master)
frame3.pack(fill=X)
# 问题
label2 = Label(frame3, text='3、您的年龄: ')
label2.grid(row=1, column=0)
# 滑动条 (Scale)
self.age = Scale(frame3, from_=0, to=100, orient=HORIZONTAL, resolution=1) # 默认垂直
self.age.grid(row=1, column=1)
# 按钮 (Button)
getage = Button(frame3, text='点击确认', command=self.getage)
getage.grid(row=1, column=2)
from_=0, to=100:设置滑条范围。
orient=HORIZONTAL:设置滑条摆放姿态,默认是垂直的。
resolution=1:设置精度。
问题四(包含列表)
# 问题4放在frame4中
frame4 = Frame(master)
frame4.pack(fill=X)
# 问题
label4 = Label(frame4, text='4、请删除您不会的编程语言: ')
label4.grid(row=1, column=0)
# 列表 (Listbox)
self.listbox = Listbox(frame4)
self.listbox.grid(row=1, column=1)
for item in ["C", "C++", 'JAVA', 'Python', 'R', 'SQL', 'JS']:
self.listbox.insert(END, item)
# 删除按钮
DELE = Button(frame4, text="删除", command=lambda listbox=self.listbox: listbox.delete(ANCHOR))
DELE.grid(row=1, column=2)
# 确定按钮
language = Button(frame4, text="确定", command=self.getlanguage)
language.grid(row=2, column=1)
获取列表中的值时,只能获取列表当前所含的所有值,或鼠标选中的值。故在设计这个多选题时,采取了将答题者不想要的答案进行删除的措施。
问题五(含画板)
# 问题5放在frame5中
frame5 = Frame(master)
frame5.pack(fill=X)
# 问题
label5 = Label(frame5, text='5、您喜欢哪种图案: ')
label5.grid(row=1, column=0)
# 画板 (Canvas)
self.canvas = Canvas(frame5, width=200, height=100, bg="White")
self.canvas.grid(row=1, column=1)
self.pattern = StringVar()
# 图案选择按钮
btRectangle = Button(frame5, text = "长方形", command = self.displayRect)
btOval = Button(frame5, text="椭 圆", command=self.displayOval)
btArc = Button(frame5, text = "圆 弧", command = self.displayArc)
btPolygon = Button(frame5, text="多边形", command=self.displayPolygon)
btLine = Button(frame5, text=" 线 ", command=self.displayLine)
btString = Button(frame5, text="确定", command=self.displayString)
btClear = Button(frame5, text="清 空", command=self.clearCanvas)
btRectangle.grid(row = 2, column = 6)
btOval.grid(row=2, column=2)
btArc.grid(row=2, column=3)
btPolygon.grid(row=2, column=4)
btLine.grid(row=2, column=5)
btString.grid(row=2, column=1)
btClear.grid(row=2, column=7)
画板上的图形类型虽然有限,但通过自己的参数调整可以做到很丰富。
问题六(包含滚轮,即拖拉条)
# 问题6放在frame6中
frame6 = Frame(master)
frame6.pack(fill=X)
# 问题
label6 = Label(frame6, text='6、您喜欢的NBA球星号: ')
label6.grid(row=1, column=0)
# 滚轮 (Scrollbar)
scrollbar = Scrollbar(frame6)
scrollbar.grid(row=1, column=2)
# 列表
self.listbox2 = Listbox(frame6,height=5, yscrollcommand=scrollbar.set)
for i in range(99):
self.listbox2.insert(END, str(i))
self.listbox2.grid(row=1, column=1)
scrollbar.config(command=self.listbox2.yview)
# 确定按钮
star = Button(frame6, text='确定', command=self.getstar)
star.grid(row=2, column=1)
很实用,无FUCK说!
还是说一句,可以获取列表当前选中的值!
问题七(包含spinbox(不知咋翻译))
# 问题7放在frame7中
frame7 = Frame(master)
frame7.pack(fill=X)
# 问题
label7 = Label(frame7, text='7、您最喜欢的数字是: ')
label7.grid(row=1, column=0)
# (Spinbox)
self.number = Spinbox(frame7, from_=0, to=10)
self.number.grid(row=1, column=1)
# 确定按钮
number = Button(frame7, text='确定', command=self.getnumber)
number.grid(row=1, column=2)
这个也很实用!可获取当前值!
问题八(包含勾选按钮)
# frame8
frame8 = Frame(master)
frame8.pack()
self.agree = StringVar()
# 勾择按钮(Checkbutton)
agree = Checkbutton(frame8, text="我确定此调查问卷信息准确无误", variable=self.agree, onvalue='确定', offvalue='不确定', command=self.getagree) # 产生选择按钮
agree.grid()
此按钮的变量为self.agree。勾选值为确定,不勾选值为不确定。
大家可能会发现,我此处的frame8.pack()中pack无参量,因为当无参量是默认将子容器放中间,这正是我想要的。
容器框
# frame10
frame10 = Frame(master)
frame10.pack()
# 容器框 (LabelFrame)
self.group = LabelFrame(frame10, text="特别鸣谢", padx=5, pady=5)
self.group.grid()
w = Label(self.group, text='本学习项目由衷感谢http://effbot.org/tkinterbook')
w.pack()
LabelFrame相当于是一个新的父容器,特别之处在于它有自己的标签。
项目纵览
项目总结
文已至此,大家应该看到了,tkinter的绝大多构件都有所呈现。相信对该模块的学习十分有用。
项目最后实现的是可以将填写的上述问题存入一个文档。
项目末尾的命令函数部分没有列出,因为如何构建界面才是本文的重点。如有兴趣,可以查看我的github:https://github.com/James95107/Tkinter
鸣谢
学习该模块花了三天,主要是看文档和一位大佬的博客,在此列出:
参考博客:http://www.jianshu.com/p/5c7a1af4aa53
学习文档:http://effbot.org/tkinterbook/
PS:本人python小白,仍在学习当中;同时也是第一次写博客,希望有缘看见此文的大佬没事多喷,也让小弟学习学习!感谢!