前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【项目实战】帮美女老师做一个点名小程序(Python tkinter)

【项目实战】帮美女老师做一个点名小程序(Python tkinter)

原创
作者头像
sidiot
发布2024-02-03 22:53:34
2430
发布2024-02-03 22:53:34
举报
文章被收录于专栏:技术大杂烩技术大杂烩

前言

博主有一个非常漂亮的老师朋友😍。最近,她急需一个能够实现随机点名的小程序,而博主正好擅长这方面的技术🤏。所以,今天博主决定为她制作一个专门用于点名的小程序💪。

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

美女老师一看,怒道:“你这做的什么东西”🤦♀️,裤裤的就给了博主两个大嘴巴子🖐️。

博主回去后痛定思痛,决定使用 Python 的 tkinter 库做一个 GUI 界面的点名程序,重新在美女老师面前找回面子🤡。

最终程序部分效果如下所示:

本文代码点击此处跳转,博文中的所有代码全部收集在博主的 GitHub 仓库中;

数据分析

当过老师的都知道,一个班级会有一本花名册,既然是点名小程序,那么肯定是需要学生的姓名的,为了防止班上有重名的同学,一般还会带上学号。

通常来说,花名册会使用 Excel 表格进行存储,因此这里引入 pandas 库进行读取,需要先安装 pandas 库:

代码语言:javascript
复制
pip install pandas
pip install openpyxl

接下来以下图的数据 demo.xlsx 为例进行分析与代码实现:


1、先读取 Excel 中的数据:

代码语言:javascript
复制
import pandas as pd
pd.read_excel("demo.xlsx")

运行结果:

2、将整体数据转换成迭代数据:

代码语言:javascript
复制
df = pd.read_excel("demo.xlsx")
for idx, row in df.iterrows():
    print(row)

运行结果:

3、获取每一行的 “序号” 值与 “姓名” 值:

代码语言:javascript
复制
for idx, row in df.iterrows():
    print(f"{row['序号']} {row['姓名']}")

运行结果:

这里可能会出现这么一个问题,传进来的 Excel 表中,没有 “序号” 或者 “姓名” 的列名,那么按照我们的逻辑,不符合我们模板要求的 Excel,我们不应该让他继续执行下去,所以这里使用 assert 进行判断:

代码语言:javascript
复制
columns = df.columns.values.tolist()
assert "序号" in columns, "需要一个名为 “序号” 的列表!"
assert "姓名" in columns, "需要一个名为 “姓名” 的列表!"

上述代码中的 df.columns.values.tolist() 是获取当前读取的 Excel 表的所有列表名称,这里的运行结果就是 ['序号', '班级', '姓名', '...']


整合上述代码

代码语言:javascript
复制
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 库:

代码语言:javascript
复制
import tkinter as tk

接下来我们就开始构建 GUI 界面了。


1、初始化一个窗口;

代码语言:javascript
复制
window = tk.Tk()
window.mainloop()

运行结果:

2、创建文字显示区域;

代码语言:javascript
复制
var = tk.StringVar(value="即 将 开 始")
show_label = tk.Label(window, textvariable=var)
show_label.pack()

在上述代码中,通过 tk.StringVar 方法创建一个字符串变量 var,并将其与标签对象 show_label 进行绑定,然后使用 pack() 方法将该标签放置在窗口中,以便显示在界面上。

运行结果:

3、创建 “开始” 与 “结束” 按钮;

代码语言:javascript
复制
btn_start = tk.Button(window, text='开始')
btn_start.pack()

btn_end = tk.Button(window, text='结束')
btn_end.pack()

运行结果:

4、实现数据滚动功能;

代码语言:javascript
复制
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 函数绑定到 “开始” 按钮上,

代码语言:javascript
复制
btn_start = tk.Button(window, text='开始', command=lambda: lottery_roll(var))

运行结果:

5、实现滚动停止功能;

前面我们已经实现了数据滚动,但我们还要让滚动停止,得出最后的结果,那么我们应该如何下手呢?

当然是从 window.after() 方法入手,因为它是实现数据滚动的关键,自然也是滚动停止的关键,我们可以设置一个标志位来判断是否还要继续执行 window.after() 方法,代码如下所示:

代码语言:javascript
复制
running = False

def lottery_start(string):
    if running:
        return
    running = True
    lottery_roll(string)

def lottery_end():
    if running:
        running = False

同时,lottery_roll 也作出相应的修改,代码如下所示:

代码语言:javascript
复制
def lottery_roll(string: tk.StringVar):
    string.set(random.choice(data))
    if running:
        window.after(50, lottery_roll, string)

运行结果:

大家可能发现程序运行时,程序并不在屏幕中间,这对一些用户来说,可能是不好的使用体验,因此我们可以在初始化的时候进行设置,代码如下所示:

代码语言:javascript
复制
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))

整合上述代码

代码语言:javascript
复制
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 = data
        self.running = False

        self.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:
            return
        self.running = True
        self.lottery_roll(string)

    def lottery_end(self):
        if self.running:
            self.running = False

优化进阶

在上述功能实现中,我们在代码里写死了文件路径,这对于程序的广泛适用性是很不友好的,因此,我们需要实现灵活获取文件并解析数据的功能。

1、初始化窗口;

代码语言:javascript
复制
window = tk.Tk()

2、创建文件路径输入框;

代码语言:javascript
复制
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、创建 “上传文件” 和 “解析数据” 按钮;

代码语言:javascript
复制
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、实现文件上传功能;

代码语言:javascript
复制
from tkinter import filedialog

def 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() 方法,然后在数据成功解析之后,销毁当前界面,跳转至点名界面。

同时,还需要对解析过程中的异常进行捕获,如果出现异常,则提示用户相关信息。

代码语言:javascript
复制
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 showwarning
        showwarning("警告", f"解析数据失败!\n{e}")

运行结果:


整合上述代码

代码语言:javascript
复制
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 showwarning
            showwarning("警告", f"解析数据失败!\n{e}")

后记

在本文中,我们一起学习了如何利用 Python 中的 tkinter 模块构建一个简单的点名小程序。通过数据分析、构建界面和优化进阶这三个部分,我们逐步完成了这个项目。从中我们不仅掌握了 Python GUI 编程的基础知识,还了解了如何优化程序以提高用户体验。

以上就是 帮美女老师做一个点名小程序(Python tkinter) 的所有内容了,希望本篇博文对大家有所帮助!欢迎大家持续关注我的博客,一起分享学习和成长的乐趣!✨

代码:

💖 我是 𝓼𝓲𝓭𝓲𝓸𝓽,期待你的关注,创作不易,请多多支持;

👍 公众号:sidiot的技术驿站

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 数据分析
  • 构建界面
  • 优化进阶
  • 后记
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档