前言
前段時間,用PyQt5寫了幾篇文章,關于Python自制一款炫酷音樂播放器、自定義動態壁紙、車牌自動識別系統,今天就繼續給大家分享一個讀者粉絲投稿的,關于上課點名的實戰案例,一起來看看是如何實作的吧!
首先我們還是一起先來看看點名器實作的效果:

下面,我們開始介紹這款點名器的制作程序,
直接跳到文末獲取原始碼及exe打包程式,
一、核心功能設計
總體來說,我們這款點名器實作的思路大致是,可以自定義設定班級學生姓名或者默認通過學號進行學生隨機點名抽取,可以每次單人抽取也可以自己選擇連抽人數進行多人連抽,并將這些隨機抽取的學生姓名歷史資料顯示,
拆解需求,接下來我們可以通過以下幾步進行實作:
- UI排版布局設計,確認點名器的各個功能設計
- 讀取班級學生的姓名檔案,將各個學生的姓名加載到串列中,如果沒有學生姓名檔案默認創建學號檔案
- 實作對學生姓名的隨機點名抽取功能
- 實作多人連抽模式
- 查看隨機抽取的學生姓名歷史資料
二、實作步驟
之前有讀者反饋說,不知道程式中具體需要哪些模塊、包檔案,下面我就把程式中用到模塊先放出來,主要包括了檔案讀寫,亂數,PyQt5,win32con等,
import sys,os
from random import randint
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import *
from win32api import MessageBox
from win32con import MB_OK, MB_ICONWARNING
1. UI排版布局設計
根據點名器所需要的功能,首先我們可以進行UI布局設計,我們這次還是使用的pyqt5,主要包含了姓名的隨機抽取顯示功能、連抽模式的隨機抽取顯示、抽取歷史結果的查看功能、姓名檔案的讀取顯示等,核心設計代碼如下:
# author:Dragon少年
def setupUi(self, MainWindow):
#以下課直接粘貼生成的setupui代碼
MainWindow.setObjectName("點名器")
MainWindow.resize(420, 360)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(55, 50, 331, 71))
font = QtGui.QFont()
font.setFamily("宋體")
font.setPointSize(50)
self.label.setFont(font)
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(55, 190, 111, 61))
font = QtGui.QFont()
font.setFamily("宋體")
font.setPointSize(20)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(253, 190, 111, 61))
font = QtGui.QFont()
font.setFamily("宋體")
font.setPointSize(20)
self.pushButton_2.setFont(font)
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(11, 570, 111, 41))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_4.setGeometry(QtCore.QRect(0, 830, 111, 41))
self.pushButton_4.setObjectName("pushButton_4")
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
self.listWidget.setGeometry(QtCore.QRect(11, 370, 397, 191))
self.listWidget.setObjectName("listWidget")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(11, 340, 210, 21))
self.label_2.setObjectName("label_2")
self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_5.setGeometry(QtCore.QRect(11, 303, 111, 20))
self.pushButton_5.setObjectName("pushButton_5")
self.pushButton_6 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_6.setGeometry(QtCore.QRect(319, 300, 75, 20))
self.pushButton_6.setObjectName("pushButton_6")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(495, 260, 56, 21))
self.label_3.setObjectName("label_3")
self.label_3.setStyleSheet('color:white;background:#222225')
self.pushButton_7 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_7.setGeometry(QtCore.QRect(649, 240, 111, 61))
font = QtGui.QFont()
font.setFamily("宋體")
font.setPointSize(30)
self.pushButton_7.setFont(font)
self.pushButton_7.setObjectName("pushButton_7")
self.listWidget_2 = QtWidgets.QListWidget(self.centralwidget)
self.listWidget_2.setGeometry(QtCore.QRect(473, 20, 353, 221))
font = QtGui.QFont()
font.setPointSize(14)
self.listWidget_2.setFont(font)
self.listWidget_2.setFocusPolicy(QtCore.Qt.WheelFocus)
self.listWidget_2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
self.listWidget_2.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) self.listWidget_2.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
self.listWidget_2.setObjectName("listWidget_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 874, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.pushButton.clicked.connect(self.start)
self.pushButton_2.clicked.connect(self.stop)
self.pushButton_5.clicked.connect(self.showHistory)
self.pushButton_6.clicked.connect(self.showContinue)
self.pushButton_7.clicked.connect(self.ten)
self.listWidget.setStyleSheet(self.scc)
self.listWidget_2.setStyleSheet(self.scc)
MainWindow.setWindowOpacity(0.95) # 設定視窗透明度
MainWindow.setAttribute(Qt.WA_TranslucentBackground)
MainWindow.setWindowFlag(Qt.FramelessWindowHint) # 隱藏邊框
self.pushButton_8 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_8.setGeometry(QtCore.QRect(132, 570, 100, 41))
self.pushButton_8.setObjectName("pushButton_8")
self.pushButton_8.clicked.connect(self.rename)
self.pushButton_8.setText('重置名字檔案')
# author:Dragon少年
def retranslateUi(self, MainWindow):
self.wide = 420
self.high = 360
_translate = QtCore.QCoreApplication.translate
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "恭喜{}號"))
self.label.setStyleSheet('color:white')
self.pushButton.setText(_translate("MainWindow", "開始"))
self.pushButton_2.setText(_translate("MainWindow", "結束"))
self.pushButton_3.setText(_translate("MainWindow", "打開名字檔案"))
self.pushButton_4.setText(_translate("MainWindow", "開gua選項"))
self.label_2.setText(_translate("MainWindow", "點過的學號/姓名:"))
self.pushButton_5.setText(_translate("MainWindow", "查看點過的名字"))
self.pushButton_6.setText(_translate("MainWindow", "連抽模式"))
self.label_3.setText(_translate("MainWindow", "連抽人數"))
self.pushButton_7.setText(_translate("MainWindow", "開始"))
UI實作效果如下:

對于這個點名器界面,之前有讀者粉絲私信我,如何實作將某些內容顯示及隱藏動態控制,今天我們就通過這個點名器進行演示實作,
例如對于這個點名器,我們想默認情況下,不要顯示抽取的學生歷史資料,也不要顯示連抽相關的內容,想讓這個點名器界面更加簡潔直觀一些,如下圖所示,

那么這個功能該如何實作呢?其實也非常簡單,只要我們定義一個事件函式,通過對界面表單的寬高進行resize重置,然后將該事件函式系結到類似按鈕點擊事件上,就可以實作動態顯示/隱藏部分界面內容了,核心代碼如下:
# author:Dragon少年
# 點擊“查看點過的名字”時,呼叫該函式,對界面表單高度大小進行resize重置
def showHistory(self):
global seed
if not seed:
self.high = 656
MainWindow.resize(self.wide,self.high)
seed = True
else:
self.high = 360
MainWindow.resize(self.wide, self.high)
seed = False
# 點擊“連抽模式”時,呼叫該函式,對界面表單寬度大小進行resize重置
def showContinue(self):
global choud
if not choud:
self.wide = 874
MainWindow.resize(self.wide, self.high)
choud = True
else:
self.wide = 420
MainWindow.resize(self.wide, self.high)
choud = False
UI布局設計完成,下面我們開始進行班級學生姓名的讀取加載,
2. 學生姓名加載
接下來我們需要對要隨機點名抽取的學生姓名進行加載放到一個串列中,這里我們需要注意是否有name.txt檔案,如果有可以直接讀取加載姓名資料,如果沒有該檔案,則需要默認根據數字進行學號檔案創建,核心代碼如下:
# author:Dragon少年
def name():
with open('name.txt', 'w') as f:
print(f.truncate())
print(f.write(a))
try:
wordlist3 = []
with open('name.txt', encoding='utf8') as f:
for line in f.readlines():
wordlist3.append(line.strip('\n')) # strip('\n')去掉字串中的'\n'
print(wordlist3)
name_list = wordlist3
except:
name()
MessageBox(0, "請及時修改當前目錄下name檔案,默認將為1-52", "MessageBox", MB_OK | MB_ICONWARNING)
name_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
'19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35',
'36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', ]
3. 隨機點名實作
隨機點名我們可以設計兩個按鈕,分別來控制開始抽取和停止抽取功能,通過定時器來進行學生姓名串列資料的隨機抽取,從而實作隨機點名的功能,核心代碼如下:
# author:Dragon少年
# 對姓名串列進行隨機顯示 模擬隨機點名功能
def setname(self):
global running
global name
try:
name = name_list[randint(0, len(name_list) - 1)]
self.label.setText("恭喜{}號!!!".format(name))
except:
self.name()
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'發生錯誤,請檢查name檔案的學號后再重新打開本軟體', QtWidgets.QMessageBox.Yes)
sys.exit()
# 開始按鈕系結 通過定時器加載隨機點名函式
def start(self):
global running
if running:
print('running')
pass
else:
self.timer = QTimer(self)
self.timer.timeout.connect(self.setname)
self.timer.start(50)
running = 'True'
# 結束按鈕系結 控制定時器停止
def stop(self):
global running, a
if running:
self.timer.stop()
running = False
self.listWidget.addItem(name)
else:
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'還沒開始就想結束?', QtWidgets.QMessageBox.Yes)
至此,我們已經可以實作點名功能了,如下所示,

4. 連抽模式實作
隨機抽取功能已經實作了,多人連抽和隨機抽取類似,只要進行姓名串列隨機抽取對應人數就可以了,當然對抽取人數的輸入,我們需要進行一些輸入限制,避免一些例外輸入情況,例如輸入非數字、輸入負數、輸入數字過大等,我們只要將連抽函式同樣系結到按鈕上就可以了,核心代碼如下:
# author:Dragon少年
def ten(self):
num = self.lineEdit.text()
print (num)
num = int(num)
if not num =='' and not num<=0 and not num>1000:
if num > 20:
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'認真的嗎,這么多', QtWidgets.QMessageBox.Yes)
self.listWidget_2.clear()
for i in range (0,int(num)):
name = name_list[randint(0, len(name_list) - 1)]
self.listWidget_2.addItem(name)
self.listWidget.addItem(name)
elif num =='':
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'請輸入數字', QtWidgets.QMessageBox.Yes)
self.listWidget_2.clear()
elif num<0:
#win32api.MessageBox(0, "你見過負數個人么???????", "通知", win32con.MB_OK | win32con.MB_ICONWARNING)
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'人數負數,輸入有誤!', QtWidgets.QMessageBox.Yes)
self.listWidget_2.clear()
elif num==0:
#win32api.MessageBox(0, "人都被你吃了???", "通知", win32con.MB_OK | win32con.MB_ICONWARNING)
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'人數為0,輸入有誤!', QtWidgets.QMessageBox.Yes)
self.listWidget_2.clear()
elif num>1000:
#win32api.MessageBox(0, "這么大?要不起~", "通知", win32con.MB_OK | win32con.MB_ICONWARNING)
reply = QtWidgets.QMessageBox.warning(self, u'警告', u'人數超出限制,輸入有誤!', QtWidgets.QMessageBox.Yes)
self.listWidget_2.clear()
5. 抽取歷史查看
我們最后再實作一個對點名的學生姓名進行歷史資料顯示查看功能,該功能實作也很簡單,只要對上面隨機抽取的姓名添加到對應的歷史串列框中就可以了;還可以對學生姓名檔案進行重置等功能,核心代碼如下:
# author:Dragon少年
def rename(self):
reply = QtWidgets.QMessageBox.question(self, u'警告', u'確定重置name檔案為1-52?', QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
with open('name.txt', 'w') as f:
print(f.truncate())
print(f.write(a))
MessageBox(0, "重置完成,", "通知", MB_OK | MB_ICONWARNING)
else:
pass
至此,這款點名器就完成了, 一起來看看效果吧!
4. 打包配置
最近有好幾個粉絲問我,Python能不能打包成exe?如何打包呢?之前已經介紹過了,今天就通過這個再來來一起介紹下,
Python常用的打包工具是第三方庫Pyinstaller,需要安裝下pyinstaller,
pip install Pyinstaller
接下來,我們需要打開命令視窗,切換到專案目錄下再執行打包命令,
pyinstaller -F -i ./img.ico 點名.py
打包常用的引數如下:
-
-F 表示生成單個可執行檔案
-
-p 表示你自己自定義需要加載的類路徑,一般情況下用不到
-
-i 表示可執行檔案的圖示
-
-w 表示去掉控制臺視窗,這在GUI界面時非常有用
之前有小伙伴問我,打包的圖示需要.ico后綴的圖片,應該如何把普通圖片轉成圖示格式.ico呢?Python也可以幫你實作圖片轉.ico檔案,核心代碼如下:
import PythonMagick
# 生成圖示ico(png格式圖片轉成ico)
img = PythonMagick.Image('./image/img1/1.png')
# 這里要設定一下尺寸,不然會報ico尺寸例外錯誤
img.sample('128x128')
img.write('./img.ico')
原始碼及打包exe已上傳,關注文末公眾號回復【點名器】即可獲取完整原始碼
Python往期精彩:
見過仙女蹦迪嗎?一起用python做個小仙女代碼蹦迪視頻
python自制一款炫酷音樂播放器,想聽啥隨便搜!
斗地主老是輸?一起用Python做個AI出牌器,豆子蹭蹭漲!
一起用Python做個車牌自動識別系統,好玩又實用!
桌面太單調?一起用Python做個自定義動態壁紙,竟然還可以放視頻!
一起用Python做個自動化彈鋼琴腳本,我竟然彈出了《天空之城》!
往期精彩原始碼均可通過下方公眾號獲取
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/304337.html
標籤:python
