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的輸出也看不到了。


好吧就是這樣吧,暑假就該多寫寫無聊的代碼打發打發時間。
這裏寫圖片描述

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