python3 做一个计时器和点名软件

突然同学要我帮忙做一个点名软件,我以为是他的大作业就答应了,结果。。。不多说了开始了
写的比较累赘,主要是打算给和我一样的萌新看的。
这里写图片描述

首先我们要一个UI

# 包含一个tk的模块,画UI需要用到
import tkinter as tk

# 创建一个应用类,继承了基础的tkinter,也就可以用到一些预先写好的组件。
class Application(tk.Frame):
    # 这个类初始化的方法
    def __init__(self, master=None):
        super().__init__(master)
        # 设置UI窗口大小
        root.geometry("250x320")
        # 设置UI窗口的标题
        root.title("点名系统")

# 利用上面写的类,创建一个应用。
root = tk.Tk()
app = Application(master=root)
app.mainloop()

这就搭出来了一个界面了,开始往里面填写内容。
稍微思考一下,要一个倒计时的功能的话,需要记录总时间,还要不断的递减时间。
记录总时间用一个变量就好了,递减时间的话,需要有一个线程不断读取剩余时间数,并按时减小时间数。

# 要用到多线程
import threading

# variable,创建一些变量,sum_time用来计时的,dec_flag就是用来实现倒计时的暂停功能。
# 对这个标记进行判断,来决定是否要继续递减时间。
sum_time = 0
dec_flag = True

# 预先设计一个线程需要实现的功能
def time_dec():
    # 获取到倒计时的数,即全局变量sum_time
    global sum_time
    # 死循环,线程按时将时间递减。
    while True:
        if int(sum_time) > 0 and dec_flag is True:
            sum_time = int(sum_time) - 1
            time.sleep(0.1)

# threading, 在这里创建线程
thrd = threading.Thread(target=time_dec)
# 将子线程设置为守护线程,一旦父线程被结束了,子线程也马上跟着结束。
thrd.setDaemon(True) 
# 开始这个线程
thrd.start()

把这一块和上面那块按规则放在一起应该就可以了。
倒计时的线程也做好了,就要开始做交互了。
交互的话,按钮和标签对于我们来说足够了。
大概也就长这样吧~
这里写图片描述
不能忘记还要抽学生点名呀!!!

# 先引用一个可以读excel的模块
import xlrd

# document,先打开一个excel文件
path = "./students.xlsx"
workbook = xlrd.open_workbook(path)
# 打开他的第一个表格,也就是sheet1
Data_sheet = workbook.sheets()[0]
# 我们只需要用到第一列,excel的第一列记录学生的姓名就好了。
# 所以这里读取一下总共共有多少行,就可以知道有多少学生了。然后生成一个随机数,抽取一个学生。
rowNum = Data_sheet.nrows

一大波代码即将来袭!!!
这一段建议只看代码注释

# 先完善一下我们的应用类,向这个里面添加上图的各种按钮。
class Application(tk.Frame):
    # 应用的初始化方法,在实例化这个类的时候被执行。
    def __init__(self, master=None):
        # super,大概也就是继承吧。
        super().__init__(master)
        root.geometry("250x320")
        root.title("点名系统")
        # 下面一长串全部是在添加按钮和标签,都具有text这个属性
        # text属性就是按钮和标签上面要显示的字
        # 按钮的话,还有一个属性叫command,也就是命令。
        # 当你点击这个按钮的时候,command绑定的方法就会被执行,方法在下面一点都有定义。
        self.get_rand_name = tk.Button(self, text="点名", command=self.choose_one)
        self.name_label = tk.Label(self, text="")
        self.get_rand_15 = tk.Button(self, text="获取随机数", command=self.get_int)
        self.show_rand = tk.Label(self, text="")
        self.cnt_1 = tk.Button(self, text="倒计时1分钟", command=self.set_time_1)
        self.cnt_2 = tk.Button(self, text="倒计时5分钟", command=self.set_time_5)
        self.pause_cnt = tk.Button(self, text="暂停/开始", command=self.rev_flag)
        self.stop_cnt = tk.Button(self, text="停止计时", command=self.reset_time)
        self.cnt_time = tk.Label(self, text=sum_time)
        # 这边command用的root.destroy就是退出程序了
        self.quit = tk.Button(self, text="QUIT", fg="red", command=root.destroy)
        # 这里的pack可以认为时将物品放到界面上,这里就是将大窗体显示在屏幕上。
        self.pack()
        # 下面的create_widgets也是一个方法,定义在后面。
        # 标签按钮创建好了,但是我们并没有将他放到我们的UI界面上。
        # 在这个create_widgets方法中,我们将决定每个小组件放的位置。
        self.create_widgets()
        # 又启动一个线程,这个线程的职责是刷新显示时间的label
        self.thrd = threading.Thread(target=self.time_dec)
        self.thrd.setDaemon(True)
        self.thrd.start()

    # 开始摆放各个小组件,我就随便放了。随意一点好^.^
    def create_widgets(self):
        self.get_rand_name.pack(side="top")
        self.name_label.pack(side="top")
        self.get_rand_15.pack(side="top")
        self.show_rand.pack(side="top")
        self.cnt_1.pack(side="top")
        self.cnt_2.pack(side="top")
        self.pause_cnt.pack(side="top")
        self.stop_cnt.pack(side="top")
        self.quit.pack(side="bottom")
        self.cnt_time.pack(side="bottom")

    # 刷新显示时间的label的线程所要用到的方法。就是获取一下剩余倒计时的时间并显示出来。
    # 事实证明,写在这个类里面的线程,会卡UI,窗口拖动都会有明显的卡顿感
    def time_dec(self):
        global sum_time
        global dec_flag
        while True:
            if dec_flag is False:
                ch = "*"
            else:
                ch = ""
            self.cnt_time["text"] = ch + str(int(sum_time / 10 / 60)) + ":" + str(int(sum_time / 10 % 60)) + "." + str(int(sum_time % 10)) + ch

    # 随机从excel文件里面抽取出一个学生点名。
    def choose_one(self):
        # 这里用到random模块生成了一个0~n-1的随机数来抽取学生。
        one_name = Data_sheet.cell_value(random.randint(0, rowNum - 1), 0)
        # 将中奖嘉宾的姓名显示在label上面^.^
        self.name_label["text"] = one_name

    # 获取一个随机数并且显示在label上面
    def get_int(self):
        self.show_rand["text"] = random.randint(1, 5)

    # 反转一下flag,减时间的线程会检查这个flag,通过这个可以实现倒计时的暂停和开始。
    @staticmethod
    def rev_flag():
        global dec_flag
        dec_flag = not dec_flag

    # 设置一个倒计时,时长为1分钟。
    @staticmethod
    def set_time_1():
        global sum_time
        sum_time = 600

    # 设置一个倒计时,时长为5分钟。
    @staticmethod
    def set_time_5():
        global sum_time
        sum_time = 3000

    # 停止计时,也相当于设置了一个倒计时,时长为0。
    @staticmethod
    def reset_time():
        global sum_time
        sum_time = 0

然后就突然发现写完了!!!
完整代码见GitHub
https://github.com/Sth32/python-dianming

顺便记录一下py文件打包成exe文件的流程

pip3 install pyinstaller
pyinstaller -F -w a.py
这样就可以将a.py这个文件打包成一个可执行的exe文件了,-F参数的作用是将各种依赖都打包在一起,在./list/文件夹下生成一个完整的可执行文件。
-w参数的作用是设置只是用窗口启动程序,不打开控制台。这样就没有黑窗了,当然程序里面用来debug的print的输出也看不到了。


好吧就是这样吧,暑假就该多写写无聊的代码打发打发时间。
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章