前言
今天教大家如何用python内置模块tkinter创建一个图形化界面且实现模拟抽卡的功能,效果如下:
导入模块
import tkinter as tk
import time,random
创建GridApp类,并往里面添加各个函数
初始化函数
class GridApp:
def __init__(self, root):
self.root = root #引用主窗口对象
self.colors = [] # 保存格子颜色的列表
self.buttons = [] # 保存格子的二维列表
self.gifts = [] # 保存奖品的二维列表
self.is_stop = True # 是否停止遍历的标志
self.create_grid() # 创建网格
self.create_start_button() # 创建开始格子
self.root.config(bg="#b0e686") # 设置窗口背景色
self.count = 0 # 记录次数
self.data = [0,0,0,0] # 记录不同类型奖品的数量 [蓝,紫,金,总共]
创建网格
def create_grid(self):# 创建网格
for i in range(4):
row = []
for j in range(4):
button = tk.Button(self.root, width=12, height=5, bg='yellowgreen',activebackground="yellowgreen")#添加一个格子按钮组件
button.grid(row=i, column=j)#固定当前格子按钮
row.append(button)#临时存放一条格子按钮数据
self.buttons.append(row)#把所有格子按钮的数据存到实例变量方便之后调用
label_1 = tk.Label(text="记录",bg="#b0e686",font=("华文彩云",20)).place(x=390,y=10)
在这个项目中,抽奖区域的格子我采用按钮的组件,这样子看起来更有立体感。
该函数用双层循环向屏幕添加按钮组件实现绘制4*4的网格,然后进行格子按钮数据的存放,再向窗口右上角添加文字标签“记录”
创建开始和停止按钮
def create_start_button(self):# 创建开始按钮
start_button = tk.Button(self.root, text='开始', command=self.start_traverse,width=10,height=3,bg="yellowgreen",relief="ridge", borderwidth=5)
start_button.grid(row=5, column=6)
def create_stop_button(self): # 创建停止按钮
stop_button = tk.Button(self.root, text='停止', command=self.stop_traverse,width=10,height=3,bg="yellowgreen")
stop_button.grid(row=5, column=6)
开始按钮中的参数relief以及borderwdth都是用来美化按钮的,对功能没有影响
而参数command对应的则是按下按钮时会触发的函数
设置奖品
def set_gifts(self):# 设置奖品
self.gifts=[[3]*4 for i in range(4)]
random_row = random.randint(0, 3)
random_col = random.randint(0, 3)
self.gifts[random_row][random_col] = 5
for i in range(2):
random_row = random.randint(0, 3)
random_col = random.randint(0, 3)
if self.gifts[random_row][random_col] == 3:
self.gifts[random_row][random_col] = 4
所有的格子下对应一个奖品,分别有13个蓝(3),2个紫(4),1个金(5),对每种奖品设置数字编号后便于之后的操作。先将所有的格子里放上蓝奖品(3),再从中随机挑选一个放上金奖品(5),最后进行两次循环,每次循环随机获得一个编号,若这个编号是3,也就是蓝奖品,将其改变成紫奖品(4)
开始抽奖
def start_traverse(self):# 开始抽奖
self.create_stop_button()#实现开始按钮按下后变成停止按钮
self.set_gifts()#设置奖品
self.is_stop = False#修改是否停止遍历的标志
while self.is_stop == False:
self.traverse_grid()#开始遍历网格
time.sleep(0.01)
self.reveal_grid(self.pre[0],self.pre[1])#循环停止时显示抽到的奖品
按下开始按钮程序就执行此函数
停止抽奖
def stop_traverse(self):# 停止抽奖
self.create_start_button()#把停止按钮恢复为开始按钮
self.is_stop = True#更新状态
重置格子
def reset_grid(self):# 重置格子的颜色为黄绿色
for i in range(4):
for j in range(4):
self.buttons[i][j].config(bg='yellowgreen')
没有重置格子颜色的后果:
显示抽奖结果
def reveal_grid(self,row,col):# 显示抽奖结果
num=self.gifts[row][col]#获取抽到的奖品编号
dic = {3:["蓝",'#1cb6e0'],4:["紫",'#c670e0'],5:["金",'#fff000']}#字典dic存放不同奖品的信息
self.data[num-3] += 1#更新抽到的各品种奖品的记录
self.data[3] += 1#更新总抽奖次数
self.buttons[row][col].config(bg=dic[num][1])#改变当前格子的颜色从而显示抽奖结果
#利用self.count控制右侧始终显示最近十次记录
if self.count == 10:
self.count = 0
tk.Label(bg="#b0e686",height=20,width=10).place(x=385,y=40)#利用无字标签遮档实现记录区域清空的效果
self.count+=1
#添加右侧界面的长方形小标签以及左下角的总记录标签
tk.Label(text=dic[num][0],bg=dic[num][1],font=("黑体",15),width=6).place(x=390,y=30+self.count*30)
tk.Label(text=f"蓝{self.data[0]}紫{self.data[1]}金{self.data[2]} 总计{self.data[3]}",font=("黑体",20),fg="green",bg='#b0e686').place(x=10,y=410)
遍历网格
def traverse_grid(self):# 遍历网格
self.reset_grid()#重置格子颜色
self.pre=[3,3]
for row in range(4):
for col in range(4):
if not self.is_stop:
self.buttons[row][col].config(bg='#72a700') # 设置当前按钮颜色为绿色
self.buttons[self.pre[0]][self.pre[1]].config(bg='yellowgreen') # 恢复上一个按钮颜色为黄绿色
time.sleep(0.01)#设置延时,使得画面不断更新呈现出滚动抽奖的效果,时间越长滚动越慢
root.update()
self.pre=[row,col]
else: #若检测到已经按下停止按钮,退出函数
return -1
这个函数会在开始抽奖函数中的while循环内反复调用,所以可以实现遍历到的方块运行到最后又返回到头上的效果,用time模块中的sleep()函数配合update()能产生动画效果
完整代码
将以上的GridApp类加入到主程序中就可以运行啦,完整代码如下
import tkinter as tk
import time,random
class GridApp:
def __init__(self, root):
self.root = root #引用主窗口对象
self.colors = [] # 保存格子颜色的列表
self.buttons = [] # 保存格子的二维列表
self.gifts = [] # 保存奖品的二维列表
self.is_stop = True # 是否停止遍历的标志
self.create_grid() # 创建网格
self.create_start_button() # 创建开始格子
self.root.config(bg="#b0e686") # 设置窗口背景色
self.count = 0 # 记录次数
self.data = [0,0,0,0] # 记录不同类型奖品的数量 [蓝,紫,金,总共]
def create_grid(self):# 创建网格
#1.双层循环实现绘制4*4的网格2.格子按钮数据的存放3.屏幕右上角添加文字标签“记录”
for i in range(4):
row = []
for j in range(4):
button = tk.Button(self.root, width=12, height=5, bg='yellowgreen',activebackground="yellowgreen")#添加一个格子按钮组件
button.grid(row=i, column=j)#固定当前格子按钮
row.append(button)#临时存放一条格子按钮数据
self.buttons.append(row)#把所有格子按钮的数据存到实例变量方便之后调用
label_1 = tk.Label(text="记录",bg="#b0e686",font=("华文彩云",20)).place(x=390,y=10)
def create_start_button(self):# 创建开始按钮
start_button = tk.Button(self.root, text='开始', command=self.start_traverse,width=10,height=3,bg="yellowgreen",relief="ridge", borderwidth=5)
start_button.grid(row=5, column=6)
def create_stop_button(self): # 创建停止按钮
stop_button = tk.Button(self.root, text='停止', command=self.stop_traverse,width=10,height=3,bg="yellowgreen")
stop_button.grid(row=5, column=6)
def set_gifts(self):# 设置奖品
#用二维数组self.gifts来存放每个格子对应的奖品的编号,分别为13个蓝(3),2个紫(4),1个金(5)
self.gifts=[[3]*4 for i in range(4)]
random_row = random.randint(0, 3)
random_col = random.randint(0, 3)
self.gifts[random_row][random_col] = 5
for i in range(2):
random_row = random.randint(0, 3)
random_col = random.randint(0, 3)
if self.gifts[random_row][random_col] == 3:
self.gifts[random_row][random_col] = 4
def start_traverse(self):# 开始抽奖
#按下开始按钮执行此函数
self.create_stop_button()#实现开始按钮按下后变成停止按钮
self.set_gifts()#设置奖品
self.is_stop = False#修改是否停止遍历的标志
while self.is_stop == False:
self.traverse_grid()#开始遍历网格
time.sleep(0.01)
self.reveal_grid(self.pre[0],self.pre[1])#循环停止时显示抽到的奖品
def stop_traverse(self):# 停止抽奖
self.create_start_button()
self.is_stop = True
def reset_grid(self):# 重置格子的颜色为黄绿色
for i in range(4):
for j in range(4):
self.buttons[i][j].config(bg='yellowgreen')
def reveal_grid(self,row,col):# 显示抽奖结果
num=self.gifts[row][col]#获取抽到的奖品编号
dic = {3:["蓝",'#1cb6e0'],4:["紫",'#c670e0'],5:["金",'#fff000']}#字典dic存放不同奖品的信息
self.data[num-3] += 1#更新抽到的各品种奖品的记录
self.data[3] += 1#更新总抽奖次数
self.buttons[row][col].config(bg=dic[num][1])#改变当前格子的颜色从而显示抽奖结果
#利用self.count控制右侧始终显示最近十次记录
if self.count == 10:
self.count = 0
tk.Label(bg="#b0e686",height=20,width=10).place(x=385,y=40)#利用无字标签遮档实现记录区域清空的效果
self.count+=1
#添加右侧界面的长方形小标签以及左下角的总记录标签
tk.Label(text=dic[num][0],bg=dic[num][1],font=("黑体",15),width=6).place(x=390,y=30+self.count*30)
tk.Label(text=f"蓝{self.data[0]}紫{self.data[1]}金{self.data[2]} 总计{self.data[3]}",font=("黑体",20),fg="green",bg='#b0e686').place(x=10,y=410)
def traverse_grid(self):# 遍历网格
self.reset_grid()#重置格子颜色
self.pre=[3,3]
for row in range(4):
for col in range(4):
if not self.is_stop:
self.buttons[row][col].config(bg='#72a700') # 设置当前按钮颜色为绿色
self.buttons[self.pre[0]][self.pre[1]].config(bg='yellowgreen') # 恢复上一个按钮颜色为黄绿色
time.sleep(0.01)#设置延时,使得画面不断更新呈现出滚动抽奖的效果,时间越长滚动越慢
root.update()
self.pre=[row,col]
else: #若检测到已经按下停止按钮,退出函数
return -1
root = tk.Tk()
root.title("抽卡模拟器(1/16出金,1/8出紫)")#设置窗口标题
app = GridApp(root)
root.mainloop()