使用pyqt5制作抽奖app

快过年了,又到了各个公司半年会抽大奖的时间了,你们行政是否找到你协助开发年会小应用呢?反正我是遇到过,不过是几年前了,今年这情况公司没年会预算……

想当年找到我的时候也是战战兢兢啊,这玩意儿还是搞个桌面应用方便啊,那时候本人还再用php,虽说php好像也出来gui扩展,不过是真心地冷,最后找度娘寻了个应付了事。后来有次年会中奖者有几个得了5万,我的心跟滴血似得,我咋就不会开发这个软件呢?钥匙我再偷偷动动手脚内定个,流口水啊。咱这正直的人也不能干这事儿不是。

说回到整体,python有好几个比较热门的gui扩展,我这里就是用pyqt5做一个简洁版的,大家可以再其基础上扩展,可不要干坏事哟。

最终效果

我这里是在Mac做的,win上一样的,我没有做打包,打包的话参考我之前的文章:python打包文件之pyinstaller。还是老规矩,我尽量将注释写到代码中

代码展示

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/12/29 10:57
# @Author : 托小尼
# @Email : 646547989@qq.com
# @URI : https://www.diandian100.cn
# @File : 抽奖.py
import os
import sys
import random

from PyQt5.QtCore import Qt, QBasicTimer
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QHBoxLayout, QVBoxLayout, QPushButton, QInputDialog, QDialog


class WinForm(QWidget):
def __init__(self):
super().__init__()
# 获取抽奖成员图片地址列表
self.imgs = self.get_imgs()
self.init_ui()


def get_imgs(self):
"""获取参与抽奖者照片路径列表"""
imgs = []
# 循环读取指定目录下所有图片
for img in os.listdir("shadow"):
# 只获取jpg和png格式的图片,并添加到抽奖列表中
if img.endswith(".png") or img.endswith(".jpg"):
imgs.append("shadow/%s" % img)
return imgs

def init_ui(self):
# 垂直layout
self.v_layout = QVBoxLayout(self)
# 抽奖初始图片
self.pic_widget = QPixmap("shadow/flag_fiji.png")
# 定义一个label,并将图片放在label中
self.pic_label = QLabel(self)
self.pic_label.setPixmap(self.pic_widget)
# pic_label.setAlignment(Qt.AlignCenter)

# 图片名称,这里即中奖者名称
self.tit_label = QLabel("标题")
# 图片标题居中
self.tit_label.setAlignment(Qt.AlignCenter)

# 创建一个计时器
self.timer = QBasicTimer()


# 修改按钮
self.btn = QPushButton("开始", self)
# 开始或停止事件绑定在按钮单击上
self.btn.clicked.connect(self.start_end)
# 居中
self.v_layout.setAlignment(Qt.AlignCenter)
# 将控件加入到我们布局中
self.v_layout.addWidget(self.pic_label)
self.v_layout.addWidget(self.tit_label)
self.v_layout.addWidget(self.btn)
self.setLayout(self.v_layout)
# 窗口大小,默认居中
self.resize(500, 300)
# 窗口标题
self.setWindowTitle("抽奖")
# 显示窗口
self.show()

def start_end(self):
"""开始结束抽奖"""
# 开始抽奖,即开启计时器,并将按钮文字改为结束,供用户停止
if self.btn.text() == "开始":
# 计时器每10毫秒运行一次
self.timer.start(10, self)
self.btn.setText("结束")
else:
self.btn.setText("开始")
# 用户点击了停止
self.timer.stop()
# 将中奖者从抽奖列表中删除
for img in self.imgs:
# 找到中奖者,将其删除,停止循环查找
if self.tit_label.text() in img:
self.imgs.remove(img)
break
# 将中奖者写入文件
with open('users.txt', 'a', encoding="utf8") as f:
f.write("%s," % self.tit_label.text())
# 弹窗提示中奖者
self.show_dialog("中奖者:%s" % self.tit_label.text())

def show_dialog(self, content="提示内容"):
# 创建QDialog对象
self.dialog = QDialog()
# 只显示关闭按钮(隐藏最大最小化按钮)
self.dialog.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint)
label = QLabel(content, self.dialog)
label.setMargin(5)
# 创建按钮到新创建的dialog对象中
btn = QPushButton('ok', self.dialog)
# 移动按钮,设置dialog的标题
btn.move(50, 50)
# 绑定关闭事件
btn.clicked.connect(self.close_dialog)
self.dialog.setWindowTitle("提示")
# 设置窗口的属性为ApplicationModal模态,用户只有关闭弹窗后,才能关闭主界面
self.dialog.setWindowModality(Qt.ApplicationModal)
self.dialog.exec_()

def close_dialog(self):
"""关闭对话框"""
self.dialog.close()

def timerEvent(self, e):
"""计时器事件"""
# 从抽奖参与者图片中随机获取一个图片路径
active_img = random.choice(self.imgs)
# 获取图片名,不含后缀
img_name= os.path.splitext(os.path.basename(active_img))[0]
# 新加一个图片
im = QPixmap(active_img)
# 添加到抽奖软件界面的抽奖者图片label中,即覆盖了原始图片
self.pic_label.setPixmap(im)
# 图片下文字修改为图片名称:即中奖者名称
self.tit_label.setText(img_name)


if __name__ == '__main__':
app = QApplication(sys.argv)
win = WinForm()
sys.exit(app.exec_())

总结

代码量还是不多的,并且本来做的比较简陋,没有做太多修饰和功能,大家可以在此基础上增加美观度,功能上也可以扩展为多个奖项,并且可以在最后显示所有中奖者,内定的事儿我不提你也会,打包下,交差吧。