@目录
一整套的简易计分器
电脑端
只要python3.8支持的计算机都能用
咳咳,图片有限使用
创作故事
来源于乒乓球……
经常和家里的小伙打打球,
来,好好打
latter……
几比几了?或者 轮到谁发球了?
于是网络上搜索了一波,并没有我想要的计分器
于是自己做一个(然后没想到做起了一套)
python创作
本计划用pyQt,而,没尝试过刚好tkinter不是很熟,就当练手。朋友们基于经验自我创造吧。本文也可以说由很多其他文章组成。
注释基本都在代码块里
tkinter
//python 3.8 QQ:2993968987 python计分器
import tkinter
from tkinter import messagebox #需要制作弹窗
#创建界面
te = tkinter.Tk()
te.title("乒乓球计分器")
te.geometry("1090x600")
#按钮兼显示
p1add = tkinter.Button(text = "0",command = p1sadd,height = 1,width = 3,font=('楷体',280),fg='#FF0000',bg='#FFF68F')
p1add.place(x=0,y=0)
p2add = tkinter.Button(text = "0",command = p2sadd,height = 1,width = 3,font=('楷体',280),fg='#FF0000',bg='#FFF68F')
p2add.place(x=546,y=0)
p1red = tkinter.Button(text = "一方撤销",command = p1sreduce,height = 1,width = 77)
p1red.place(x=0,y=540)
p2red = tkinter.Button(text = "一方撤销",command = p2sreduce,height = 1,width = 77)
p2red.place(x=546,y=540)
reset = tkinter.Button(text = "重置",command = resetsoce,height = 1,width = 78)
reset.place(x=245,y=570)
#部件安放
p1sdp = tkinter.Label(te,text = " ",font=('楷体',40),fg='#76EE00',bg='#FFF68F')
p1sdp.place(x=220,y=0)
p2sdp = tkinter.Label(te,text = " ",font=('楷体',40),fg='#76EE00',bg='#FFF68F')
p2sdp.place(x=780,y=0)
#退出
turn_out = tkinter.Button(text = "退出",command = outline,height = 1,width = 40)
turn_out.place(x=800,y=570)
#创作信息
information = tkinter.Button(text = "创作信息",command = information,height = 1,width = 40)
information.place(x=0,y=570)
#键盘操控
te.bind('<Key-Left>',p1sa)
te.bind('<Key-Right>',p2sa)
#上面的函数暂时不能用,这些是我从编写好的程序中拷贝的
te.mainloop()#循环
一大串函数命令
#分数增加
#seve用着判断发球者
def p1sadd():
global a,b,seve
if a == 1 and b == 0 and seve == 1:
a = 0
else:
a += 1
disupate()
def p2sadd():
global a,b,seve
if b == 1 and a == 0 and seve ==1:
a = b
else:
b += 1
disupate()
#键盘操控
def p1sa(event):
global a
a += 1
disupate()
def p2sa(event):
global b
b += 1
disupate()
#分数减少
def p1sreduce():
global a,seve,sevehelp
if a > 0:
a -= 1
seve -= 1
sevehelp = seve - 1
disupate()
def p2sreduce():
global b,seve,sevehelp
if b > 0:
b -= 1
seve -= 1
sevehelp = seve - 1
disupate()
#显示刷新
def disupate():
global seve,sevehelp
p1add['text']= a
p2add['text']= b
# print(text_score)
#重置
def resetsoce():
global a,b,gamenumber,totallscore,seve,sevehelp
a = 0
b = 0
totallscore = a + b
seve = 1
sevehelp = 1
p1add['text']= a
p2add['text']= b
p1sdp['text']= " "
p2sdp['text']= " "
gamenumber += 1
#退出
def outline():
global gamenumber
te.destroy()
print(gamenumber)
#创作信息
def information():
tkinter.messagebox.showinfo(title='创作信息', message='作者:鹰下是海 QQ:2993968987
#发球显示
def dispsev_a():
p1sdp['text']= "发球"
p2sdp['text']= " "
global a,b,seve
if a == 1 and b == 0 and seve ==1:
a = 0
disupate()
def dispsev_b():
global a,b,seve
p2sdp['text']= "发球"
p1sdp['text']= " "
if b == 1 and a == 0 and seve ==1:
b = 0
disupate()
有些多余繁琐也是正常的,比较懒
多线程
进行发球者判定
#发球者判定
seve = (-1)
sevehelp = 1
def serv():
global a,b,totallscore,seve,sevehelp
while True:
try:
if a == 1 and b == 0 and seve ==1:
seve = 3
sevehelp = 3
dispsev_a()
a -= 1
if b == 1 and a == 0 and seve ==1:
seve = 4
sevehelp = 4
dispsev_b()
b -= 1
else:
if totallscore%2 == 0 and totallscore <= 20 and totallscore >> 0 and seve == sevehelp:
time.sleep(0.5)
seve += 1
if totallscore == 20:
sevehelp = totallscore
if seve%2 == 1 and seve >> 1:
dispsev_a()
if seve%2 == 0 and seve >> 1:
dispsev_b()
if totallscore%2 == 1 and totallscore << 20 and totallscore >> 0 and seve == (sevehelp + 1):
if sevehelp != seve:
sevehelp = seve
#if totallscore%2 == 1 and totallscore << 20 and totallscore >> 0 and seve == sevehelp:
# sevehelp -= 1
if totallscore >= 21:
if totallscore == sevehelp + 1:
time.sleep(0.5)
seve += 1
sevehelp += 1
if totallscore == 0 and (seve == 2 or seve == 1):
resetsoce()
except:
pass
#子线程发球者判定启动
s_04 = threading.Thread(target=serv,name="thread4")
s_04.setDaemon(True)
s_04.start()
不过这之前需要用到总成绩等,为了编写时方便我将结果统计放在了另一个线程
结果统计
#结果统计(运用多线程)
totallscore = a + b
text_score = str(a) + str(b)
def totall():
global a,b,totallscore,text_score,state
while True:
totallscore = a + b
text_score = str(a) + ':' + str(b)
time.sleep(1)
#print(totallscore)
#print(text_score)
#结果判定
if a >= 11 and b <= 9:
tkinter.messagebox.showinfo(title='结果', message='玩家二胜利')
resetsoce()
if b >= 11 and a <= 9:
tkinter.messagebox.showinfo(title='结果', message='玩家一胜利')
resetsoce()
if totallscore >=22:
if (a - b) == 2:
tkinter.messagebox.showinfo(title='结果', message='玩家二胜利')
resetsoce()
if (b - a) == 2:
tkinter.messagebox.showinfo(title='结果', message='玩家一胜利')
resetsoce()
#子线程结果统计启动
t_01 = threading.Thread(target=totall,name="thread1")
t_01.setDaemon(True)
t_01.start()
在tkinker里添加一一个记录保存
物联网加持
物联网连接与信息获取
#物联网控制(运用多线程)
mqtt = paho.mqtt.client
#MQtt加持
resi = "no"
rese = "no"
def on_connect(client,userdata, flags, rc):
#print("Connected with result code "+str(rc)) #打印连接状态
client.subscribe("主题") #订阅的主题
def on_message(client, userdata, msg):
global resi
resi =("%s"%(msg.payload))
#print(resi)#打印接受的消息
#为防止意外使用了多线程来进行信息获取
#值替换,需要在内部部获取替换到外部
def mqmseeg():
global resi,rese
while True:
rese = (resi[2:7])
t_03 = threading.Thread(target=mqmseeg,name="thread3")
t_03.setDaemon(True)
t_03.start()
#def mqhelp():
client_id = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
client = mqtt.Client(client_id) # ClientId不能重复,所以使用当前时间
client.username_pw_set("IOT ID", "IOT Password") # 必须设置,否则会返回「Connected with result code 4」,就是错误嘛
#client.username_pw_set("iot id", "iot key")
client.on_connect = on_connect
client.on_message = on_message
client.connect("IOT address", 1883, 60)
#client.loop_forever()
client.loop_start()#循环
接着就要用MQtt来控制
物联网控制
这里只写了手机控制电脑,要是需要电脑控制其他设备的话,只要使用“主题发布”然后适当用些延时(避免电脑用MQtt再次控制自己,也可删除部分控制函数),注意运行顺序
#物联网控制
def mqcontrol():
global a,b,rese,resi,seve,sevehelp
while True:
time.sleep(1)
if rese == "p1add":
p1sadd()
if rese == "p1red":
p1sreduce()
if rese == "p2add":
p2sadd()
if rese == "p2red":
p2sreduce()
if rese == "reset":
resetsoce()
if rese == "outli":
resi = "no"
outline()
#pass#outline
#有发生一打开程序便退出,需要检查:如果使用移动端退出电脑端程序且网络响应过慢则需要更该变量(rese),应为该变量储存为了“outli”,那你就替换代码(比如使用:pass)运行并需要在物联网控制平台发送其他内容来更改该变量
if rese == "p1res":
a = 0
if rese == "p2res":
b = 0
if rese == "p1sev":
resi = "no"
#p1sadd()
p1sadd()
if rese == "p2sev":
resi = "no"
#p2sadd()
p2sadd()
resi = "no"
#子线程物联网控制启动
m_01 = threading.Thread(target=mqcontrol,name="thread2")
m_01.setDaemon(True)
m_01.start()
这样程序就完成了
这个程序不难,写不了多少
来看一下效果
实际文件代码可能与文章略有所不同
计分器套装使用
整套应用(已打包)
整套应用(代码)
目前存在两种撤销情况会使“发球者”显示错误,但我可能不会对该漏洞进行修复
网页版的正在制作