前言

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

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

博主在美人教师面前吹完牛皮之后,当场翻开 Python,引进 random 库,直接返回了一个随机整数值。

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

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

博主回去后痛定思痛,决定运用 Python 的 tkinter 库做一个 GUI 界面的点名程序,从头在美人教师面前找回体面。

最终程序部分作用如下所示:

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

本文代码点击此处跳转,往期系列文章请拜访博主的项目实战专栏,博文中的一切代码全部收集在博主的 GitHub 库房中;

数据剖析

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

一般来说,花名册会运用 Excel 表格进行存储,因此这儿引进 pandas 库进行读取,需求先装置 pandas 库:

pip install pandas
pip install openpyxl

接下来以下图的数据 demo.xlsx 为例进行剖析与代码完成:

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


1、先读取 Excel 中的数据:

import pandas as pd
pd.read_excel("demo.xlsx")

运转成果:

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

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

df = pd.read_excel("demo.xlsx")
for idx, row in df.iterrows():
    print(row)

运转成果:

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

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

for idx, row in df.iterrows():
    print(f"{row['序号']} {row['名字']}")

运转成果:

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

这儿可能会呈现这么一个问题,传进来的 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()

运转成果:

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

2、创立文字显现区域;

var = tk.StringVar(value="即 将 开 始")
show_label = tk.Label(window, textvariable=var)
show_label.pack()

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

运转成果:

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

3、创立 “开端” 与 “完毕” 按钮;

btn_start = tk.Button(window, text='开端')
btn_start.pack()
btn_end = tk.Button(window, text='完毕')
btn_end.pack()

运转成果:

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

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 = False
def lottery_start(string):
    if running:
        return
    running = True
    lottery_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 = 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、初始化窗口;

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)

运转成果:

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

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)

运转成果:

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

4、完成文件上传功用;

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 文件)。

运转成果:

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

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 showwarning
        showwarning("警告", f"解析数据失败!n{e}")

运转成果:

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


整合上述代码

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)的一切内容了,期望本篇博文对大家有所帮助!欢迎大家持续关注我的博客,一同分享学习和成长的趣味!✨

代码:

上篇精讲:基于 MobileNetV3 完成恶意文件静态检测(下)

我是,期待你的关注,创造不易,请多多支撑;

大众号:sidiot的技能驿站

系列专栏:项目实战Python