Python实现上课点名器系统
⽬录
前⾔
⼀、核⼼功能设计
⼆、实现步骤
1. UI排版布局设计
2. 学⽣姓名加载
3. 随机点名实现
4. 连抽模式实现
5. 抽取历史查看
三. 打包配置
总结
前⾔
前段时间,⽤PyQt5写了⼏篇⽂章,关于Python⾃制⼀款炫酷⾳乐播放器、⾃定义动态壁纸、车牌⾃动识别系统。今天就继续给⼤家分享⼀个读者粉丝投稿的,关于上课点名的实战案例,⼀起来看看是如何实现的吧!
⾸先我们还是⼀起先来看看点名器实现的效果:
下⾯,我们开始介绍这款点名器的制作过程。
直接跳到⽂末获取源码及exe打包程序。
⼀、核⼼功能设计
总体来说,我们这款点名器实现的思路⼤致是,可以⾃定义设置班级学⽣姓名或者默认通过学号进⾏学⽣随机点名抽取,可以每次单⼈抽取也可以⾃⼰选择连抽⼈数进⾏多⼈连抽,并将这些随机抽取的学⽣姓名历史数据显⽰。
拆解需求,接下来我们可以通过以下⼏步进⾏实现:
1.UI排版布局设计,确认点名器的各个功能设计
2.读取班级学⽣的姓名⽂件,将各个学⽣的姓名加载到列表中,如果没有学⽣姓名⽂件默认创建学号⽂件
3.实现对学⽣姓名的随机点名抽取功能
4.实现多⼈连抽模式
5.查看随机抽取的学⽣姓名历史数据
⼆、实现步骤
之前有读者反馈说,不知道程序中具体需要哪些模块、包⽂件,下⾯我就把程序中⽤到模块先放出来。主要包括了⽂件读写,随机
数,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("点名器")
self.label = QtWidgets.alwidget)
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.alwidget)
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.alwidget)
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.alwidget)
self.pushButton_3.setGeometry(QtCore.QRect(11, 570, 111, 41))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_4 = QtWidgets.alwidget)
self.pushButton_4.setGeometry(QtCore.QRect(0, 830, 111, 41))
self.pushButton_4.setObjectName("pushButton_4")
self.listWidget = QtWidgets.alwidget)
self.listWidget.setGeometry(QtCore.QRect(11, 370, 397, 191))
self.listWidget.setObjectName("listWidget")
self.label_2 = QtWidgets.alwidget)
self.label_2.setGeometry(QtCore.QRect(11, 340, 210, 21))
self.label_2.setObjectName("label_2")
self.pushButton_5 = QtWidgets.alwidget)
self.pushButton_5.setGeometry(QtCore.QRect(11, 303, 111, 20))
self.pushButton_5.setObjectName("pushButton_5")
self.pushButton_6 = QtWidgets.alwidget)
self.pushButton_6.setGeometry(QtCore.QRect(319, 300, 75, 20))
self.pushButton_6.setObjectName("pushButton_6")
self.label_3 = QtWidgets.alwidget)
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.alwidget)
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.alwidget)
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.alwidget)
MainWindow.ubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
resize函数c++MainWindow.setStatusBar(self.statusbar)
tSlotsByName(MainWindow)
self.t(self.start)
self.pushButton_t(self.stop)
self.pushButton_t(self.showHistory)
self.pushButton_t(self.showContinue)
self.pushButton_)
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.alwidget)
self.pushButton_8.setGeometry(QtCore.QRect(132, 570, 100, 41))
self.pushButton_8.setObjectName("pushButton_8")
self.pushButton_ame)
self.pushButton_8.setText('重置名字⽂件')
# author:Dragon少年
def retranslateUi(self, MainWindow):
self.wide = 420
self.high = 360
_translate = anslate
_translate = anslate
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
seed = True
else:
self.high = 360
seed = False
# 点击“连抽模式”时,调⽤该函数,对界⾯窗体宽度⼤⼩进⾏resize重置
def showContinue(self):
global choud
if not choud:
self.wide = 874
choud = True
else:
self.wide = 420
choud = False
UI布局设计完成,下⾯我们开始进⾏班级学⽣姓名的读取加载。
2. 学⽣姓名加载
接下来我们需要对要随机点名抽取的学⽣姓名进⾏加载放到⼀个列表中,这⾥我们需要注意是否有⽂件,如果有可以直接读取加载姓名数据,如果没有该⽂件,则需要默认根据数字进⾏学号⽂件创建。核⼼代码如下:
# author:Dragon少年
def name():
with open('', 'w') as f:
uncate())
print(f.write(a))
try:
wordlist3 = []
with open('', encoding='utf8') as f:
for line adlines():
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)
# 开始按钮绑定通过定时器加载随机点名函数
def start(self):
global running
if running:
print('running')
pass
else:
self.timer = QTimer(self)
self.t(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 = ()
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)