【项目实战】帮美女老师做一个点名小程序(Python tkinter)
前言
博主有一个非常漂亮的老师朋友😍。最近,她急需一个能够实现随机点名的小程序,而博主正好擅长这方面的技术🤏。所以,今天博主决定为她制作一个专门用于点名的小程序💪。

博主在美女老师面前吹完牛皮之后,当场打开 Python,引入 random 库,直接返回了一个随机整数值😏。

美女老师一看,怒道:“你这做的什么东西”🤦♀️,裤裤的就给了博主两个大嘴巴子🖐️。
博主回去后痛定思痛,决定使用 Python 的 tkinter 库做一个 GUI 界面的点名程序,重新在美女老师面前找回面子🤡。
最终程序部分效果如下所示:

数据分析
当过老师的都知道,一个班级会有一本花名册,既然是点名小程序,那么肯定是需要学生的姓名的,为了防止班上有重名的同学,一般还会带上学号。
通常来说,花名册会使用 Excel 表格进行存储,因此这里引入 pandas 库进行读取,需要先安装 pandas 库:
pip install pandas
pip install openpyxl
接下来以下图的数据 demo.xlsx 为例进行分析与代码实现:

1、先读取 Excel 中的数据:
import pandas as pd
pd.read_excel("demo.xlsx")
运行结果:

2、将整体数据转换成迭代数据:
df = pd.read_excel("demo.xlsx")
for idx, row in df.iterrows():print(row)
运行结果:

3、获取每一行的 “序号” 值与 “姓名” 值:
for idx, row in df.iterrows():print(f"{row['序号']} {row['姓名']}")
运行结果:

这里可能会出现这么一个问题,传进来的 Excel 表中,没有 “序号” 或者 “姓名” 的列名,那么按照我们的逻辑,不符合我们模板要求的 Excel,我们不应该让他继续执行下去,所以这里使用 assert 进行判断:
columns = df.columns.values.tolist()
assert "序号" in columns, "需要一个名为 “序号” 的列表!"
assert "姓名" in columns, "需要一个名为 “姓名” 的列表!"
上述代码中的 df.columns.values.tolist() 是获取当前读取的 Excel 表的所有列表名称,这里的运行结果就是 ['序号', '班级', '姓名', '...']。
整合上述代码
def deal_data(filepath):df = pd.read_excel(filepath)columns = df.columns.values.tolist()assert "序号" in columns, "需要一个名为 “序号” 的列表!"assert "姓名" in columns, "需要一个名为 “姓名” 的列表!"return [f"{row['序号']} {row['姓名']}" for idx, row in df.iterrows()]
构建界面
我们使用 tkinter 来构建可视化界面,引入 tkinter 库:
import tkinter as tk
接下来我们就开始构建 GUI 界面了。
1、初始化一个窗口;
window = tk.Tk()
window.mainloop()
运行结果:

2、创建文字显示区域;
var = tk.StringVar(value="即 将 开 始")
show_label = tk.Label(window, textvariable=var)
show_label.pack()
在上述代码中,通过 tk.StringVar 方法创建一个字符串变量 var,并将其与标签对象 show_label 进行绑定,然后使用 pack() 方法将该标签放置在窗口中,以便显示在界面上。
运行结果:

3、创建 “开始” 与 “结束” 按钮;
btn_start = tk.Button(window, text='开始')
btn_start.pack()btn_end = tk.Button(window, text='结束')
btn_end.pack()
运行结果:

4、实现数据滚动功能;
data = [f"{row['序号']} {row['姓名']}" for idx, row in df.iterrows()]def lottery_roll(string: tk.StringVar):string.set(random.choice(data))window.after(50, lottery_roll, string)
在上述代码中,data 数据来自于读取 Excel 表格,lottery_roll 实现了数据滚动效果,其原理是通过 string.set(random.choice(data)) 这行代码从 data 中随机选择一个元素,并将其设置为 string 的值,然后使用 window.after() 方法在50毫秒之后继续调用 lottery_roll 函数,再次随机选择数据并更新界面。
最后将 lottery_roll 函数绑定到 “开始” 按钮上,
btn_start = tk.Button(window, text='开始', command=lambda: lottery_roll(var))
运行结果:

5、实现滚动停止功能;
前面我们已经实现了数据滚动,但我们还要让滚动停止,得出最后的结果,那么我们应该如何下手呢?
当然是从 window.after() 方法入手,因为它是实现数据滚动的关键,自然也是滚动停止的关键,我们可以设置一个标志位来判断是否还要继续执行 window.after() 方法,代码如下所示:
running = Falsedef lottery_start(string):if running:returnrunning = Truelottery_roll(string)def lottery_end():if running:running = False
同时,lottery_roll 也作出相应的修改,代码如下所示:
def lottery_roll(string: tk.StringVar):string.set(random.choice(data))if running:window.after(50, lottery_roll, string)
运行结果:

大家可能发现程序运行时,程序并不在屏幕中间,这对一些用户来说,可能是不好的使用体验,因此我们可以在初始化的时候进行设置,代码如下所示:
def center_window(root: tk.Tk, w, h):# 获取屏幕 宽、高ws = root.winfo_screenwidth()hs = root.winfo_screenheight()# 计算 x, y 位置x = (ws / 2) - (w / 2)y = (hs / 2) - (h / 2)root.geometry('%dx%d+%d+%d' % (w, h, x, y))
整合上述代码
def center_window(root: tk.Tk, w, h):# 获取屏幕 宽、高ws = root.winfo_screenwidth()hs = root.winfo_screenheight()# 计算 x, y 位置x = (ws / 2) - (w / 2)y = (hs / 2) - (h / 2)root.geometry('%dx%d+%d+%d' % (w, h, x, y))class CallWindow(tk.Tk):def __init__(self, data):super().__init__()self.data = dataself.running = Falseself.title("无奖问答")center_window(self, 405, 300)self.var = tk.StringVar(value="即 将 开 始")self.show_label = tk.Label(self,textvariable=self.var,)self.show_label.pack()self.btn_start = tk.Button(self,text='开始',command=lambda: self.lottery_start(self.var),)self.btn_start.pack()self.btn_end = tk.Button(self,text='结束',command=lambda: self.lottery_end(),)self.btn_end.pack()def lottery_roll(self, string):string.set(random.choice(self.data))if self.running:self.after(50, self.lottery_roll, string)def lottery_start(self, string):if self.running:returnself.running = Trueself.lottery_roll(string)def lottery_end(self):if self.running:self.running = False
优化进阶
在上述功能实现中,我们在代码里写死了文件路径,这对于程序的广泛适用性是很不友好的,因此,我们需要实现灵活获取文件并解析数据的功能。
1、初始化窗口;
window = tk.Tk()
2、创建文件路径输入框;
label_filepath = tk.Label(window, text="文件路径")
label_filepath.grid(row=0, column=0, padx=(10, 0), pady=10)
entry_filepath = tk.Entry(window)
entry_filepath.grid(row=0, column=1, columnspan=2, padx=(0, 10), ipadx=60)
运行结果:

3、创建 “上传文件” 和 “解析数据” 按钮;
btn_upload_file = tk.Button(window, text="上传文件")
btn_upload_file.grid(row=2, column=1, pady=10, ipadx=30)
btn_parse_data = tk.Button(window, text="解析数据")
btn_parse_data.grid(row=2, column=2, ipadx=30)
运行结果:

4、实现文件上传功能;
from tkinter import filedialogdef upload_file(entry: tk.Entry):filepath = filedialog.askopenfilename(title="请选择一个文件", filetypes=[("Excel", ".xls .xlsx")])entry.delete(0, tk.END)entry.insert(0, filepath)
在上述代码中,filedialog.askopenfilename() 方法弹出一个文件选择对话框供用户选择文件,并且通过 filetypes 指定了可以选择的文件类型为 Excel 文件(.xls 或 .xlsx 文件)。
运行结果:

5、实现数据解析功能;
读取 Excel 的功能实现参照前面讲过的 deal_data() 方法,然后在数据成功解析之后,销毁当前界面,跳转至点名界面。
同时,还需要对解析过程中的异常进行捕获,如果出现异常,则提示用户相关信息。
def parse_data(root, entry_filepath):try:data = deal_data(entry_filepath.get())root.destroy()CallWindow(data)except Exception as e:from tkinter.messagebox import showwarningshowwarning("警告", f"解析数据失败!\n{e}")
运行结果:

整合上述代码
class UploadWindow(tk.Tk):def __init__(self):super().__init__()self.title("上传")center_window(self, 350, 100)self.label_filepath = tk.Label(self, text="文件路径")self.label_filepath.grid(row=0, column=0, padx=(10, 0), pady=10)self.entry_filepath = tk.Entry(self)self.entry_filepath.grid(row=0, column=1, columnspan=2, padx=(0, 10), ipadx=60)self.btn_upload_file = tk.Button(self, text="上传文件", command=self.upload_file)self.btn_upload_file.grid(row=2, column=1, pady=10, ipadx=30)self.btn_parse_data = tk.Button(self, text="解析数据", command=self.parse_data)self.btn_parse_data.grid(row=2, column=2, ipadx=30)def upload_file(self):filepath = filedialog.askopenfilename(title="请选择一个文件", filetypes=[("Excel", ".xls .xlsx")])self.entry_filepath.delete(0, tk.END)self.entry_filepath.insert(0, filepath)def parse_data(self):try:data = deal_data(self.entry_filepath.get())self.destroy()CallWindow(data)except Exception as e:from tkinter.messagebox import showwarningshowwarning("警告", f"解析数据失败!\n{e}")
后记
在本文中,我们一起学习了如何利用 Python 中的 tkinter 模块构建一个简单的点名小程序。通过数据分析、构建界面和优化进阶这三个部分,我们逐步完成了这个项目。从中我们不仅掌握了 Python GUI 编程的基础知识,还了解了如何优化程序以提高用户体验。
以上就是 帮美女老师做一个点名小程序(Python tkinter) 的所有内容了,希望本篇博文对大家有所帮助!欢迎大家持续关注我的博客,一起分享学习和成长的乐趣!✨
如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!
😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

1️⃣零基础入门
① 学习路线
对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

② 路线对应学习视频
还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~

③练习题
每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!

2️⃣国内外Python书籍、文档
① 文档和书籍资料

3️⃣Python工具包+项目源码合集
①Python工具包
学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!

②Python实战案例
光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!

③Python小游戏源码
如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!

4️⃣Python面试题
我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。


上述所有资料 ⚡️ ,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓

相关文章:
【项目实战】帮美女老师做一个点名小程序(Python tkinter)
前言 博主有一个非常漂亮的老师朋友😍。最近,她急需一个能够实现随机点名的小程序,而博主正好擅长这方面的技术🤏。所以,今天博主决定为她制作一个专门用于点名的小程序💪。 博主在美女老师面前吹完牛皮之…...
Elasticsearch 去重后求和
标题的要求可以用如下 SQL 表示 select sum(column2) from (select distinct(column1),column2 from table)t 要如何用 DSL 实现呢,先准备下索引和数据 PUT test_index {"mappings": {"properties": {"column1": {"type"…...
考研数学——高数:函数与极限(3)
函数的连续性与间断点 函数的连续性 左连续 右连续 区间上的连续性 在xo处连续 函数的间断点 第一类间断点(左右极限都存在) 可去间断点: f(xo-0)= f(xo+0) 跳跃间断点: f(xo-0)≠ f(xo+0) 第二类间断点(震荡间断点、无穷间断点)...
LeetCode49 字母异位词分组
LeetCode49 字母异位词分组 在这篇博客中,我们将探讨 LeetCode 上的一道经典算法问题:字母异位词分组。这个问题要求将给定的字符串数组中的字母异位词组合在一起,并以任意顺序返回结果列表。 问题描述 给定一个字符串数组 strs࿰…...
【Python】Windows本地映射远程Linux服务器上的端口(解决jupyter notebook无法启动问题)
创作日志: 学习深度学习不想在本地破电脑上再安装各种软件,我就用实验室的服务器配置环境,启动jupyter notebook时脑子又瓦特了,在自己Windows电脑上打开服务器提供的网址,那肯定打不开啊,以前在其它电脑上…...
C++面试:用户态和内核态的基本概念、区别
目录 一、基本概念 概念: 区别: 二、Windows示例 基础介绍 用户态到内核态的切换过程: 程序实例 三、Linux示例 特权级别: 用户态到内核态的切换过程: 调度和中断处理: 程序实例 总结 在操作系…...
Vue计算属性computed()
1. 计算属性定义 获取计算属性值 <div>{{ 计算属性名称}}</div>创建计算属性 let 定义的属性ref/reactive....let 计算属性名称 computed(() > {//这里写函数式,函数式里面包含定义属性//只有这个包含的定义属性被修改时才出发此函数式//通过计算属性名称co…...
JWT学习笔记
了解 JWT Token 释义及使用 | Authing 文档 JSON Web Token Introduction - jwt.io JSON Web Token (JWT,RFC 7519 (opens new window)),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519)。该 token 被设计为紧凑…...
WSL里的Ubuntu 登录密码忘了怎么更改
环境: Win10 专业版 WSL2 如何 Ubuntu22.04 问题描述: WSL里的Ubuntu 登录密码忘了怎么更改 解决方案: 在WSL中的Ubuntu系统中,忘记了密码,可以通过以下步骤重置密码: 1.打开命令提示符或PowerShel…...
【软件测试面试】要你介绍项目-如何说?完美面试攻略...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、测试面试时&am…...
【Crypto | CTF】RSA打法 集合
天命:我发现题题不一样,已知跟求知的需求都不一样 题目一:已知 p q E ,计算T,最后求D 已知两个质数p q 和 公钥E ,通过p和q计算出欧拉函数T,最后求私钥D 【密码学 | CTF】BUUCTF RSA-CSDN…...
在springboot中调用openai Api并实现流式响应
之前在《在springboot项目中调用openai API及我遇到的问题》这篇博客中,我实现了在springboot中调用openai接口,但是在这里的返回的信息是一次性全部返回的,如果返回的文字比较多,我们可能需要等很久。 所以需要考虑将请求接口响应…...
C++构造函数重难点解析
一、C构造函数是什么 C的构造函数是一种特殊的成员函数,用于初始化类的对象。它具有与类相同的名称,并且没有返回类型。构造函数在创建对象时自动调用,并且可以执行必要的初始化操作。 二、C构造函数特点 类的构造函数不能被继承,…...
QT day3 作业2.22
思维导图: 作业: 完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到…...
AR汽车行业解决方案系列之2-远程汽修
在汽车行业中,AR技术的应用正悄然改变着整个产业链的运作方式,应用涵盖培训、汽修、汽车售后、PDI交付、质检以及汽车装配等,AR技术为多个环节都带来了前所未有的便利与效率提升。 安宝特AR将以系列推文的形式为读者逐一介绍在汽车行业中安宝…...
每日五道java面试题之spring篇(五)
目录: 第一题. 使用 Spring 有哪些方式?第二题. 什么是Spring IOC 容器?第三题. 控制反转(IoC)有什么作用?第四题. IOC的优点是什么?第五题. BeanFactory 和 ApplicationContext有什么区别? 第一题. 使用 Spring 有哪…...
挑战杯 基于YOLO实现的口罩佩戴检测 - python opemcv 深度学习
文章目录 0 前言1 课题介绍2 算法原理2.1 算法简介2.2 网络架构 3 关键代码4 数据集4.1 安装4.2 打开4.3 选择yolo标注格式4.4 打标签4.5 保存 5 训练6 实现效果6.1 pyqt实现简单GUI6.3 视频识别效果6.4 摄像头实时识别 7 最后 0 前言 🔥 优质竞赛项目系列…...
12. Springboot集成Dubbo3(三)Dubbo-Admin
目录 1、前言 2、安装 2.1、下载Dubbo-admin 2.2、修改配置 2.3、编译前端 2.4、访问 2.5、加载自己的服务 2.6、服务测试 2.7、其他 3、小结 1、前言 Dubbo Admin是用于管理Dubbo服务的基于Web的管理工具。Dubbo Admin提供了一个用户友好的界面,用于在分…...
c语言的数据结构:找环状链表入口处
一起<( ̄︶ ̄)↗[GO!] 1.如何判断一个链表是否有环 思路:设定两个快慢指针fast和slow,fast每次走两个结点,slow每次走一个节点 如果fast指针遇到了Null,那么这个链表没有环,如果fast和slow可以相遇,则代表这个链表有环 代码如下 N:fast先进环,slow后…...
LabVIEW声速测定实验数据处理
LabVIEW声速测定实验数据处理 介绍了一个基于LabVIEW的声速测定实验数据处理系统的应用。该系统利用LabVIEW的强大数据处理和分析能力,通过设计友好的用户界面和高效的算法,有效提高了声速测定实验的数据处理效率和准确性。通过这个案例,可以…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护
摘要 本文以健康管理应用为例,展示鸿蒙系统如何通过细粒度权限控制、动态权限授予、数据隔离和加密存储四大核心机制,实现复杂场景下的用户隐私保护。我们将通过完整的权限请求流程和敏感数据处理代码,演示鸿蒙系统如何平衡功能需求与隐私安…...
如何使用CodeRider插件在IDEA中生成代码
一、环境搭建与插件安装 1.1 环境准备 名称要求说明操作系统Windows 11JetBrains IDEIntelliJ IDEA 2025.1.1.1 (Community Edition)硬件配置推荐16GB内存50GB磁盘空间 1.2 插件安装流程 步骤1:市场安装 打开IDEA,进入File → Settings → Plugins搜…...
