‍♂️ 个人主页:@艾派森的个人主页

✍作者简介:Python学习者
希望大家多多支持,我们一起进步!
如果文章对你有帮助的话,
欢迎评论 点赞 收藏 加关注+


目录

一、Tkinter

二、最终效果

三、项目过程

3.1分析布局

3.2创建窗口

3.3构建题库

3.4创建组件

3.5编写事件函数

四、总结

源代码


一、Tkinter

什么是GUI
图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。与通过键盘输入文本或字符命令来完成例行任务的字符界面相比,图形用户界面有许多优点。图形用户界面由窗口、下拉菜单、对话框及其相应的控制机制构成,在各种新式应用程序中都是标准化的,即相同的操作总是以同样的方式来完成,在图形用户界面,用户看到和操作的都是图形对象,应用的是计算机图形学的技术。

GUI 编程类似于“搭积木”,将一个个组件(Widget)放到窗口中。如下是 windows 中的 画图软件,就是一个典型的 GUI 程序:

常用的 GUI 库

1. Tkinter

tkinter(Tk interface)是 Python 的标准 GUI 库,支持跨平台的 GUI 程序开发。tkinter 适合小型的 GUI 程序编写,也特别适合初学者学习 GUI 编程。本次以 tkinter 为核心进行讲解。关于Tkinter基础知识可参考Tkinter保姆级教程(上)和Tkinter保姆级教程(下)

2. wxPython

wxPython 是比较流行的 GUI 库,适合大型应用程序开发,功能强于 tkinter,整体设计 框架类似于 MFC(Microsoft Foundation Classes 微软基础类库)。

3. PyQT

Qt 是一种开源的 GUI 库,适合大型 GUI 程序开发,PyQT 是 Qt 工具包标准的 Python 实现。我们也可以使用 Qt Desginer 界面设计器快速开发 GUI 应用程序 。

一个最简单的 Tkinter 程序至少应包含以下四个部分:

  • 导入 tkinter 模块
  • 创建主窗口,也称 root 窗口(即根窗口)
  • 添加人机交互控件,同时编写相应的事件函数
  • 通过主循环(mainloop)来显示主窗口

二、最终效果

先来看看本次项目的最终效果:

项目运行之后,程序会从题库中随机抽取10道题目来测试,当你答对或答错都会有弹窗提示,答对一道得10分,当题目全部答完后会提示你题目已做完,并显示你本次考试的最终得分。话不多说,开始上教程。

三、项目过程

3.1分析布局

由于本次只是做一个简易的答题程序,所以整体页面不需要太复杂。首先,需要Label标签来显示每道题的题目,接着就是4个垂直摆放(或横向)单选框按钮,最后下面放个下一题的点击按钮。

3.2创建窗口

做任何项目,都需要先创建主窗口,也称 root 窗口(即根窗口)。

# 导入本次项目用到的库import tkinterfrom tkinter import *from tkinter.messagebox import *import randomif __name__ == '__main__':root = tkinter.Tk()# 创建tkinter对象root.title('垃圾分类答题考试')# 设置标题root.geometry("500x200+500+300") # 设置页面的位置和长宽root.mainloop() # 让窗口一直显示出来

效果如下:

3.3构建题库

本次做的是垃圾分类的答题程序,所以我在网上找了一些关于垃圾分类的题目。这里我就直接用列表套元组的方式来存储数据了。说明一下,元组中的第一个是题目,后面依次是ABCD选项,最后是本题的答案选项。

# 准备一个题库列表object_list = [('包了口香糖的纸巾属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('保鲜膜属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('变质的香肠属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('槟榔渣属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('剥掉的蛋壳属于哪一类垃圾" /># 导入本次项目用到的库import tkinterfrom tkinter import *from tkinter.messagebox import *import random# 准备一个题库列表object_list = [('包了口香糖的纸巾属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('保鲜膜属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('变质的香肠属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('槟榔渣属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('剥掉的蛋壳属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('菜刀属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('茶叶渣应扔进哪个垃圾桶?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('吃剩的饼干渣是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('抽完烟的烟蒂是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('刀片属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('掉在地上的树叶是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('废弃的食用油属于?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('甘蔗渣是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('过期的化妆品是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('过期的猫粮属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('包装药片的铝箔属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('喝茶剩下的茶叶渣是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('花生壳属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('坏掉的电脑属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('灰色塑料袋属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('回形针属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('鸡骨头属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('鸡毛属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('家庭盆栽废弃的树叶是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('碱性电池属于什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('胶卷属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('旧凉席属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('旧图书属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('空的灭火器属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('老旧电视机属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('落发属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('没用完的铅笔属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('没有泡过的茶叶属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('哪一类可进行资源再生利用?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('苹果手机电池属于什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('破碎的碗碟属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('染发剂的容器属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('杀虫剂的容器属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('水果硬糖属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('水银温度计属于什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('撕掉了的旧照片,应该丢到哪个垃圾桶内?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'B'), ('塑料筷子属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('塑料玩具是什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'C'), ('糖果包装纸属于什么垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('西瓜籽属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ]if __name__ == '__main__':root = tkinter.Tk()# 创建tkinter对象root.title('垃圾分类答题考试')# 设置标题root.geometry("500x200+500+300") # 设置页面的位置和长宽# 从题库中随机抽取10个题目作为考试题values = random.sample(object_list,10)# 创建一个字符串变量用来记录选项值s = tkinter.StringVar()s.set('E')# 设置初始值为'E',初始没选中# 设置初始题号和分值num = 0score = 0label = tkinter.Label(root, text=values[num][0])# 用来显示题目label.pack()# 创建第 1 个 Frame 组件f1 = Frame(root)f1.pack()r1 = tkinter.Radiobutton(f1, variable=s, value='A', text=values[num][1])# 安装第一个单选按钮r1.pack()r2 = tkinter.Radiobutton(f1, variable=s, value='B', text=values[num][2])# 安装第二个单选按钮r2.pack()r3 = tkinter.Radiobutton(f1, variable=s, value='C', text=values[num][3])# 安装第三个单选按钮r3.pack()r4 = tkinter.Radiobutton(f1, variable=s, value='D', text=values[num][4])# 安装第四个单选按钮r4.pack()# 创建第 2 个 Frame 组件f2 = Frame(root)f2.pack()# 创建下一题的按钮Button(f2, text='下一题').pack(side=LEFT)# 默认显示第一道题目label["text"] = str(num+1) + '.' + values[num][0]# 显示题目# 显示4个选项r1["text"] = values[num][1]r2["text"] = values[num][2]r3["text"] = values[num][3]r4["text"] = values[num][4]root.mainloop() # 让窗口一直显示出来

效果如下:

现在你点击下一题是没有反应的,因为此时只是实现了页面的布局工作,还没有实现判断对错的功能。

3.5编写事件函数

事件的逻辑是当你点击下一题按钮的时候,程序判断你对本题的选项是否与题库中的答案一致,如果相等,则通过弹窗的形式提示你答对了;如果不相等,则通过弹窗的形式提示你答错了。提示完之后还要紧接着显示下一道题目。每次判断完之后都要检测本题是否已经是最后一道题目,如果是则停止答题,得出本次测试的总得分。

# 定义一个判断选项正确性的函数def main(values):# 全局引用num和score变量global num global score# 如果选项和答案相等则答对了if s.get() == values[num][5]:showinfo("恭喜", "恭喜你答对了!")# 提示你答对了score += 10# 得分加10分# 如果选项和答案不相等则答错了else:showinfo("遗憾", "遗憾你答错了!")# 提示你答错了num = num + 1# 记录题号# 如果题号已经大于等于题目的总长度则需要进行结束并统计总分数if num >= len(values):showinfo("结果", f"全部题目做完了!\n您的最终得分为{score}分!")# 提示题目做完了,总结出你的得分root.quit()# 程序退出return# 显示下一题label["text"] = str(num+1) + '.' + values[num][0] # 显示题目# 显示4个选项r1["text"] = values[num][1]r2["text"] = values[num][2]r3["text"] = values[num][3]r4["text"] = values[num][4]s.set('E')# 设置初始值为'E',初始没选中

同时还需要在下一题按钮那添加该事件函数

Button(f2, text='下一题', command=lambda:main(values)).pack(side=LEFT)

到这里一个简易版的答题程序已经实现,效果如前面所示。

四、总结

本次使用了Python中的tkinter库实现了一个简易的垃圾分类答题程序,其中的题库和各种参数大家可以发挥自己的创意,自行进行修改,基于此源码的基础上创作出你的作品!

源代码

# 导入本次项目用到的库import tkinterfrom tkinter import *from tkinter.messagebox import *import random# 准备一个题库列表object_list = [('包了口香糖的纸巾属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('保鲜膜属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'A'), ('变质的香肠属于哪一类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('槟榔渣属于哪类垃圾?', '其他垃圾', '有害垃圾', '可回收物', '厨余垃圾', 'D'), ('剥掉的蛋壳属于哪一类垃圾" />= len(values):showinfo("结果", f"全部题目做完了!\n您的最终得分为{score}分!")# 提示题目做完了,总结出你的得分root.quit()# 程序退出return# 显示下一题label["text"] = str(num+1) + '.' + values[num][0] # 显示题目# 显示4个选项r1["text"] = values[num][1]r2["text"] = values[num][2]r3["text"] = values[num][3]r4["text"] = values[num][4]s.set('E')# 设置初始值为'E',初始没选中if __name__ == '__main__':root = tkinter.Tk()# 创建tkinter对象root.title('垃圾分类答题考试')# 设置标题root.geometry("500x200+500+300") # 设置页面的位置和长宽# 从题库中随机抽取10个题目作为考试题values = random.sample(object_list,10)# 创建一个字符串变量用来记录选项值s = tkinter.StringVar()s.set('E')# 设置初始值为'E',初始没选中# 设置初始题号和分值num = 0score = 0label = tkinter.Label(root, text=values[num][0])# 用来显示题目label.pack()# 创建第 1 个 Frame 组件f1 = Frame(root)f1.pack()r1 = tkinter.Radiobutton(f1, variable=s, value='A', text=values[num][1])# 安装第一个单选按钮r1.pack()r2 = tkinter.Radiobutton(f1, variable=s, value='B', text=values[num][2])# 安装第二个单选按钮r2.pack()r3 = tkinter.Radiobutton(f1, variable=s, value='C', text=values[num][3])# 安装第三个单选按钮r3.pack()r4 = tkinter.Radiobutton(f1, variable=s, value='D', text=values[num][4])# 安装第四个单选按钮r4.pack()# 创建第 2 个 Frame 组件f2 = Frame(root)f2.pack()# 创建下一题的按钮Button(f2, text='下一题', command=lambda:main(values)).pack(side=LEFT)# 默认显示第一道题目label["text"] = str(num+1) + '.' + values[num][0]# 显示题目# 显示4个选项r1["text"] = values[num][1]r2["text"] = values[num][2]r3["text"] = values[num][3]r4["text"] = values[num][4]root.mainloop()