最近在作業中面向社群玩家組織了一場活動,需要進行隨機抽獎,參考之前小明大佬的案例,再結合自己的需求,做了一個簡單的隨機抽獎小工具,
今天我就來順便介紹一下這個小工具的制作程序吧!

1. 核心功能設計
針對隨機抽獎的小工具,需要可以匯入參與抽獎的人員名單,然后選擇不同的獎勵型別進行隨機抽取獲獎名單并匯出,
那么,簡單進行需求拆解,大致梳理出以下核心功能:
?名單匯入
為了避免出現重名情況,這里我們約定以下幾點:
①匯入參與抽獎的人員名單檔案(xlsx型別檔案)
②資料第一列為ID,第二列為name
參考格式案例

?獎項型別選擇
獎項型別是指一等獎、二等獎這類標識語,這里我們內置了特等獎-六等獎共7個選項供選取
?本輪人數
本輪人數是指每次抽獎時一次性抽取的獲獎人數,默認值為5
①當填入的數字超過剩余未獲獎人數時,會進行提示并顯示未獲獎人數
②當填入的數字為0表示輪空,也需要手動結束
③當填入的數字為負數時,點擊抽獎無回應
④當填入的非數字時,會進行提示需要輸入正確數字
?抽獎時輪播區域
用于顯示抽獎中隨機滾動參與本輪抽獎的人員名單
?人員名單
當選擇正確的人員名單檔案后,這里會自動顯示人員資訊串列
?中獎記錄
記錄每次抽取的獎項型別及獲獎名單
?開始抽獎
①開始抽獎時,會先判斷抽獎設定是否滿足條件,否則會有相關提示
②抽獎中點擊開始抽獎會提示正在抽獎中
?結束
①非抽獎狀態下點擊結束無回應
②抽獎中點擊結束將顯示本次抽獎結果
?重置
①重置會清掉歷史抽獎記錄(含本地檔案,如有必要建議對中獎名單留檔)
②抽獎中點擊重置會提示正在抽獎中
③非抽獎狀態點擊重置會提示該操作會洗掉歷史記錄,是否確認
基本功能點確認后,我們就開始進行GUI設計,

2. GUI設計與實作
基于功能點,我們用axure簡單進行UI布局設計,然后再通過GUI開發庫進行設計,這里依舊采用的是pysimplegui,主要是簡單方
便,
Python學習交流Q群:906715085### UI布局設計-axure 基于GUI設計,我們編碼如下: nameList_column = [ [sg.Text('人員名單:')], [sg.Listbox(values=[], size=(20, 10), key='nameList')], ] result_column = [ [sg.Text('中獎記錄:')], [sg.Multiline('', size=(48, 10), key='result', text_color='DeepPink')], ] # 主題設定 sg.theme('SystemDefaultForReal') # 布局設定 layout = [[sg.Text('選擇參與抽獎人員名單檔案:', font=('微軟雅黑', 12)), sg.InputText('', key='_file', size=(50, 1), font=('微軟雅黑', 10), enable_events=True), sg.FileBrowse('打開', file_types=(('Text Files', '*.xlsx'),), size=(10, 1), font=('微軟雅黑', 11))], [sg.Frame(layout=[ [sg.Text('本輪獎項:', font=('微軟雅黑', 12)), sg.Combo(['特等獎', '一等獎', '二等獎', '三等獎', '四等獎', '五等獎', '六等獎'], font=('微軟雅黑', 10), default_value=https://www.cnblogs.com/123456feng/archive/2022/04/15/'特等獎', size=(15, 5), key='_type'), sg.Text('本輪人數:', font=('微軟雅黑', 12)), sg.InputText('5', key='_num', size=(38, 1), font=('微軟雅黑', 10))], ], title='抽獎設定', title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='請進行抽獎設定后再開始抽獎')], [sg.Multiline(size=(48, 5), font=( '微軟雅黑', 18), text_color='Blue', key='luckyName', justification='center')], [sg.Column(nameList_column), sg.Column(result_column)], [sg.Text('操作說明:', font=('微軟雅黑', 12))], [sg.Text('①先選擇參與抽獎的人員名單xlsx檔案,人員名單檔案包含ID和name兩個欄位\n②獲獎名單將存在小工具所在檔案夾,重置會洗掉歷史記錄檔案', font=('微軟雅黑', 10)), sg.Text('', font=('微軟雅黑', 12), size=(5, 1)), sg.Button('開始抽獎', font=('微軟雅黑', 12), button_color='Orange'), sg.Button('結束', font=('微軟雅黑', 12), button_color='red'), sg.Button('重置', font=('微軟雅黑', 12), button_color='red'), ], ] # 創建視窗 window = sg.Window('抽獎小工具,作者@微信公眾號:可以叫我才哥', layout, font=('微軟雅黑', 12), default_element_size=(50, 1))
其包含的控制元件如下:
?Text 文本
?InputText 輸入文本框
?FileBrowse 檔案瀏覽
?Multiline 多行文本框
?Combo 下拉框
?Listbox 串列
?Button 按鈕
需要注意的是這里有個Frame組件,用于layout嵌套,可以很好地模塊化UI布局,

3. 功能實作
在本案例中,需要實作三個功能,分別是:讀取人員名單、隨機抽獎以及保存中獎名單,
3.1 讀取人員名單
這里采用的是openpyxl讀取表格資料并獲得某幾列的值,由于存在表頭,所以最后不需要表頭
Python學習交流Q群:906715085### def nameList(window): fileName = values['_file'] try: wb = openpyxl.load_workbook(fileName) active_sheet = wb.active names = [cell_object.value for cell_object in list(active_sheet.columns)[1]][1:] ids = [cell_object.value for cell_object in list(active_sheet.columns)[0]][1:] names = [name+'_'+str(id_) for name, id_ in zip(names, ids)] window['nameList'].update(names) return names except: sg.popup('請選擇正確格式的的人員名單檔案', title='提示',)
3.2. 隨機抽獎
由于我們需要一次隨機抽取的人數存在多個,所以這里用的是random.sample(),需要注意的是傳入的引數中names是需要去掉已
中獎名單
def Result(window, names): global is_run, luckyNames _type = values['_type'] # 本輪獎項型別 _num = int(values['_num']) # 本輪人數 while True: randomName = random.sample(names, k=_num) luckyName = ' '.join(randomName) window['luckyName'].update(luckyName) if not is_run: headers = ['獎項', '名單'] toCsv(headers, [_type]*len(randomName), randomName, lucky) luckyNames = luckyNames + _type+' : '+luckyName+'\n\n' window['result'].update(luckyNames) return time.sleep(0.088)
3.3. 保存中獎名單
這里我們用的是csv庫的方法,追加存盤
def toCsv(headers, col1, col2, file): # 存在則追加,不存在則新建 if os.path.exists(lucky): with open(lucky, 'a', encoding='utf_8_sig', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerows(zip(col1, col2)) else: with open(lucky, 'w', encoding='utf_8_sig', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerow(headers) writer.writerows(zip(col1, col2))
完成核心功能函式后,我們再進行GUI互動邏輯的實作,

3.4. GUI互動邏輯
這里有兩個全域變數,其中一個用于記錄當前抽獎狀態,另外一個用于存盤當前已經獲獎的人員資訊,關于互動邏輯的詳情,大
家可以結合核心功能需求及以下代碼了解,
Python學習交流Q群:906715085### # 初始狀態 is_run = False luckyNames = '' # 事件回圈 while True: event, values = window.read() if event in (None, '關閉程式'): break if event == '_file': nameList(window) if event == '開始抽獎': if is_run: sg.popup('抽獎進行中,無需重復操作......', title='提示') continue try: names = nameList(window) # 人員名單 _num = int(values['_num']) # 本輪人數 lucky = '中獎名單.csv' # 中獎名單 if os.path.exists(lucky): with open('中獎名單.csv', 'r', encoding='utf_8_sig') as f: reader = csv.reader(f) selectedNames = set([i[1] for i in reader][1:]) names_set = set(names)-selectedNames else: names_set = set(names) if len(names_set) >= _num: is_run = True _thread.start_new_thread(Result, (window, names_set)) else: sg.popup( f'請選擇正確本輪抽獎人數(當前 {len(names_set)} 個未中獎人數)', title='提示') except: sg.popup('請選擇正確本輪抽獎人數(別超過總人數哦)', title='提示') elif event == '結束': is_run = False elif event == '重置': if is_run: sg.popup('抽獎進行中,請等待抽獎結束后重置...', title='提示') continue yes_no = sg.popup_yes_no( '重置會清楚歷史資料,是否執行此操作??', text_color='red', title='提示') if yes_no == 'Yes': try: os.remove(lucky) luckyNames = '' window['result'].update(luckyNames) window['luckyName'].update(luckyNames) sg.popup('抽獎歷史記錄已被重置......', title='提示') except: sg.popup('無抽獎歷史記錄......', title='提示') window.close()
基于此,我們就完成了隨機抽獎小工具的制作,
啟動頁如下:

最后,大家感興趣就可以將代碼打包成exe可執行檔案了,我這邊打包下來大概10MB左右大小,
以上就是本文全部內容,如果你感興趣,點個贊和在看支持一下唄,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/458272.html
標籤:其他
上一篇:IDEA Debug程序中使用Drop Frame或Reset Frame實作操作回退
下一篇:面向小白的Python可視化教程
