|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 北光念晨 于 2022-1-5 17:44 编辑 个人觉得比较好的,用python做的随机点名器。各位大佬不喜勿喷哈~
# from tkinter import * # 图形界面
# from tkinter import messagebox # 对话框
from tkinter import filedialog #文件操作
# from sys import exc_info # 用于抛出异常
from traceback import format_exc #用于精准的获取错误异常
from os.path import exists # 文件、路径是否存在
from random import sample # 从列表里随机抽取
from random import randint # 生成随机数字
from tkinter import colorchooser # 用于选择颜色
try:
from .jsondata import * # 用于保存数据
from .updata import * # 用于文件更新
except:
from jsondata import * # 用于保存数据
from updata import * # 用于文件更新
# updata([0,0,0,0])
file = 'names.txt'
names = []
background = "#f0f0f0"
buttonbg = "#f0f0f0"
havenames = []
animation = False
# json数据文件名称/地址
json_data_file = 'data.json'
# 初始化数据
data = {
'cumulative': 0, # 累计人数
'font_size': 100, # 字号
'file': 'names.txt', # 姓名文件
'background': "#f0f0f0", # 背景色
'buttonbg': "#f0f0f0", # 按钮背景色
'-alpha': 1.0, # 透明度
'-topmost': False, # 是否置于顶层
'program_name': 'RandomRollCall', #程序名
'program_path': sys.argv[0], # 程序路径
'verson': [1, 1, 0, 2], # 版本号
'time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), # 时间
'check_code': '', # 校验码
}
data_default = data.copy() # 数据默认值
bbh = "%i.%i.%i.%i"%tuple([data['verson'][i] for i in range(4)]) # 版本号
colors = '''#FFB6C1 LightPink 浅粉红
#FFC0CB Pink 粉红
#DC143C Crimson 深红/猩红
#FFF0F5 LavenderBlush 淡紫红
#DB7093 PaleVioletRed 弱紫罗兰红
#FF69B4 HotPink 热情的粉红
#FF1493 DeepPink 深粉红
#C71585 MediumVioletRed 中紫罗兰红
#DA70D6 Orchid 暗紫色/兰花紫
#D8BFD8 Thistle 蓟色
#DDA0DD Plum 洋李色/李子紫
#EE82EE Violet 紫罗兰
#FF00FF Magenta 洋红/玫瑰红
#FF00FF Fuchsia 紫红/灯笼海棠
#8B008B DarkMagenta 深洋红
#800080 Purple 紫色
#BA55D3 MediumOrchid 中兰花紫
#9400D3 DarkViolet 暗紫罗兰
#9932CC DarkOrchid 暗兰花紫
#4B0082 Indigo 靛青/紫兰色
#8A2BE2 BlueViolet 蓝紫罗兰
#9370DB MediumPurple 中紫色
#7B68EE MediumSlateBlue 中暗蓝色/中板岩蓝
#6A5ACD SlateBlue 石蓝色/板岩蓝
#483D8B DarkSlateBlue 暗灰蓝色/暗板岩蓝
#E6E6FA Lavender 淡紫色/熏衣草淡紫
#F8F8FF GhostWhite 幽灵白
#0000FF Blue 纯蓝
#0000CD MediumBlue 中蓝色
#191970 MidnightBlue 午夜蓝
#00008B DarkBlue 暗蓝色
#000080 Navy 海军蓝
#4169E1 RoyalBlue 皇家蓝/宝蓝
#6495ED CornflowerBlue 矢车菊蓝
#B0C4DE LightSteelBlue 亮钢蓝
#778899 LightSlateGray 亮蓝灰/亮石板灰
#708090 SlateGray 灰石色/石板灰
#1E90FF DodgerBlue 闪兰色/道奇蓝
#F0F8FF AliceBlue 爱丽丝蓝
#4682B4 SteelBlue 钢蓝/铁青
#87CEFA LightSkyBlue 亮天蓝色
#87CEEB SkyBlue 天蓝色
#00BFFF DeepSkyBlue 深天蓝
#ADD8E6 LightBlue 亮蓝
#B0E0E6 PowderBlue 粉蓝色/火药青
#5F9EA0 CadetBlue 军兰色/军服蓝
#F0FFFF Azure 蔚蓝色
#E0FFFF LightCyan 淡青色
#AFEEEE PaleTurquoise 弱绿宝石
#00FFFF Cyan 青色
#00FFFF Aqua 浅绿色/水色
#00CED1 DarkTurquoise 暗绿宝石
#2F4F4F DarkSlateGray 暗瓦灰色/暗石板灰
#008B8B DarkCyan 暗青色
#008080 Teal 水鸭色
#48D1CC MediumTurquoise 中绿宝石
#20B2AA LightSeaGreen 浅海洋绿
#40E0D0 Turquoise 绿宝石
#7FFFD4 Aquamarine 宝石碧绿
#66CDAA MediumAquamarine 中宝石碧绿
#00FA9A MediumSpringGreen 中春绿色
#F5FFFA MintCream 薄荷奶油
#00FF7F SpringGreen 春绿色
#3CB371 MediumSeaGreen 中海洋绿
#2E8B57 SeaGreen 海洋绿
#F0FFF0 Honeydew 蜜色/蜜瓜色
#90EE90 LightGreen 淡绿色
#98FB98 PaleGreen 弱绿色
#8FBC8F DarkSeaGreen 暗海洋绿
#32CD32 LimeGreen 闪光深绿
#00FF00 Lime 闪光绿
#228B22 ForestGreen 森林绿
#008000 Green 纯绿
#006400 DarkGreen 暗绿色
#7FFF00 Chartreuse 黄绿色/查特酒绿
#7CFC00 LawnGreen 草绿色/草坪绿
#ADFF2F GreenYellow 绿黄色
#556B2F DarkOliveGreen 暗橄榄绿
#9ACD32 YellowGreen 黄绿色
#6B8E23 OliveDrab 橄榄褐色
#F5F5DC Beige 米色/灰棕色
#FAFAD2 LightGoldenrodYellow 亮菊黄
#FFFFF0 Ivory 象牙色
#FFFFE0 LightYellow 浅黄色
#FFFF00 Yellow 纯黄
#808000 Olive 橄榄
#BDB76B DarkKhaki 暗黄褐色/深卡叽布
#FFFACD LemonChiffon 柠檬绸
#EEE8AA PaleGoldenrod 灰菊黄/苍麒麟色
#F0E68C Khaki 黄褐色/卡叽布
#FFD700 Gold 金色
#FFF8DC Cornsilk 玉米丝色
#DAA520 Goldenrod 金菊黄
#B8860B DarkGoldenrod 暗金菊黄
#FFFAF0 FloralWhite 花的白色
#FDF5E6 OldLace 老花色/旧蕾丝
#F5DEB3 Wheat 浅黄色/小麦色
#FFE4B5 Moccasin 鹿皮色/鹿皮靴
#FFA500 Orange 橙色
#FFEFD5 PapayaWhip 番木色/番木瓜
#FFEBCD BlanchedAlmond 白杏色
#FFDEAD NavajoWhite 纳瓦白/土著白
#FAEBD7 AntiqueWhite 古董白
#D2B48C Tan 茶色
#DEB887 BurlyWood 硬木色
#FFE4C4 Bisque 陶坯黄
#FF8C00 DarkOrange 深橙色
#FAF0E6 Linen 亚麻布
#CD853F Peru 秘鲁色
#FFDAB9 PeachPuff 桃肉色
#F4A460 SandyBrown 沙棕色
#D2691E Chocolate 巧克力色
#8B4513 SaddleBrown 重褐色/马鞍棕色
#FFF5EE Seashell 海贝壳
#A0522D Sienna 黄土赭色
#FFA07A LightSalmon 浅鲑鱼肉色
#FF7F50 Coral 珊瑚
#FF4500 OrangeRed 橙红色
#E9967A DarkSalmon 深鲜肉/鲑鱼色
#FF6347 Tomato 番茄红
#FFE4E1 MistyRose 浅玫瑰色/薄雾玫瑰
#FA8072 Salmon 鲜肉/鲑鱼色
#FFFAFA Snow 雪白色
#F08080 LightCoral 淡珊瑚色
#BC8F8F RosyBrown 玫瑰棕色
#CD5C5C IndianRed 印度红
#FF0000 Red 纯红
#A52A2A Brown 棕色
#B22222 FireBrick 火砖色/耐火砖
#8B0000 DarkRed 深红色
#800000 Maroon 栗色
#FFFFFF White 纯白
#F5F5F5 WhiteSmoke 白烟
#DCDCDC Gainsboro 淡灰色
#D3D3D3 LightGrey 浅灰色
#C0C0C0 Silver 银灰色
#A9A9A9 DarkGray 深灰色
#808080 Gray 灰色
#696969 DimGray 暗淡灰
#000000 Black 纯黑'''
def choice():
global file
filename = filedialog.askopenfilename(
title = '打开--请选择包含姓名的TXT文件',
filetypes=[('TXT', '*.txt'),
('All Files', '*')],
#initialdir='C:\\Windows'),
)
if filename != '':
file = filename
vname_file.set(file)
def save_changes():
global names
b = True
string = ''
global data
global f21
global f31
global havenames
try:
name_file = vname_file.get()
if not exists(name_file):
b = False
string += '未找到文件,文件“%s”不存在!' % name_file
else:
f = open(name_file, 'r')
names = f.readlines()
f.close()
for i in range(len(names)):
if i != len(names) - 1:
names[i] = names[i][:-1]
else:
if names[i][-1] == "\n":
names[i] = names[i][:-1]
for i in range(len(names)):
while i < len(names) and names[i] == "":
del names[i]
names = list(set(names))
data['file'] = name_file
print(names)
except:
b = False
string += '读取文件“%s”失败!\n' % vname_file.get()
try:
f21['bg'] = vbackground.get()
data['background'] = vbackground.get()
except:
b = False
string += '未知背景颜色“%s”!\n' % vbackground.get()
try:
f31['bg'] = vbuttonbg.get()
data['buttonbg'] = vbuttonbg.get()
except:
b = False
string += '未知按钮颜色“%s”!\n' % vbuttonbg.get()
if b:
data['background'] = vbackground.get()
data['buttonbg'] = vbuttonbg.get()
data['font_size'] = int(var_font_size_Scale.get())
# data['-topmost'] = var__topmost_Checkbutton.get()
havenames = []
save_data(data, json_data_file)
wset_up.destroy()# 销毁设置窗口
else:
messagebox.showerror(title='数据错误!',message=string)
def restore_default():
global file
global background
global buttonbg
global f21
global f31
file = data_default['file']
background = data_default['background']
buttonbg = data_default['buttonbg']
f21['bg'] = data_default['background']
f31['bg'] = data_default['buttonbg']
vname_file.set(data_default['file'])
vbackground.set(data_default['background'])
vbuttonbg.set(data_default['buttonbg'])
var_font_size_Scale.set(data_default['font_size'])
def first_read():
global names
try:
name_file = data['file']
if not exists(name_file):
pass
else:
f = open(name_file, 'r')
names = f.readlines()
f.close()
for i in range(len(names)):
if i != len(names) - 1:
names[i] = names[i][:-1]
else:
if names[i][-1] == "\n":
names[i] = names[i][:-1]
for i in range(len(names)):
while i < len(names) and names[i] == "":
del names[i]
names = list(set(names))
data['file'] = name_file
print(names)
except:
pass
if names == []:
print('暂无姓名!')
def change_background_color(color):
global f21
try:
f21['bg'] = color
except:
pass
return True
def change_buttonbg_color(color):
global f31
try:
f31['bg'] = color
except:
pass
return True
def colorchooser_change_background_color():
color = colorchooser.askcolor(data['background'])
if color[1] != None:
vbackground.set(color[1])
def colorchooser_change_buttonbg_color():
color = colorchooser.askcolor(data['buttonbg'])
if color[1] != None:
vbuttonbg.set(color[1])
def no_repeat_roll_call():
if var_no_repeat_roll_call.get():
reset_Button.pack(side=LEFT)
remaining_names_Lable.pack(side=LEFT)
else:
reset_Button.pack_forget()
remaining_names_Lable.pack_forget()
def reset():
global havenames
remaining_names_Lable['text'] = "剩余姓名:"+str(len(names))+'/'+ str(len(names))
havenames = []
def extract_animation():
random_roll_call_Button['state'] = DISABLED
start_pause_Button['state'] = DISABLED
if len(names) > 7:
randomnames = sample(names, 7)
else:
randomnames = names
for i in range(len(randomnames)):
lname['text'] = randomnames[i]
time.sleep((i + 1) / 35)
global data
if not var_no_repeat_roll_call.get():
name = sample(names, 1)[0]
else:
global havenames
randomhavenames = names.copy()
for havename in havenames:
randomhavenames.remove(havename)
name = sample(randomhavenames, 1)[0]
havenames.append(name)
if len(havenames) == len(names):
havenames = []
else:
pass
remaining_names_Lable['text'] = '剩余姓名:'+str(len(names)-len(havenames))+'/'+ str(len(names))
print(havenames)
lname['text'] = name
data['cumulative'] += 1
cumulative_Label['text'] = '累计抽取人数:' + str(data['cumulative'])
random_roll_call_Button['state'] = NORMAL
start_pause_Button['state'] = NORMAL
exit() # 退出线程
def random_roll_call():
if len(names) == 0:
messagebox.showerror(title = '没有指定姓名文件',
message='没有指定姓名文件!\n或姓名文件被删除!\
\n或姓名文件为空\n请先指明姓名文件!')
else:
# 开始抽取线程
threading.Thread(target=extract_animation).start()
def clearing():
global data
data['cumulative'] = 0
cumulative_Label['text'] = '累计抽取人数:0'
def roll_call_begins():
print('开始了')
global data
zz = len(names)-1
sj = randint(0,len(names)-1)
for i in range(sj ,len(names)-1):
if animation:
lname['text'] = names[i]
time.sleep(0.02)
else:
break
while animation:
if zz == -1:
zz = len(names)-1
lname['text'] = names[zz]
zz -= 1
time.sleep(0.02)
def start_pause():
global animation
global data
if len(names) == 0:
messagebox.showerror(title = '没有指定姓名文件',
message='没有指定姓名文件!\n或姓名文件被删除!\n请先指明姓名文件!')
else:
if animation:
random_roll_call_Button['state'] = NORMAL
animation = False
start_pause_Button['text'] = '开始点名'
data['cumulative'] += 1
cumulative_Label['text'] = '累计抽取人数:' + str(data['cumulative'])
else:
animation = True
random_roll_call_Button['state'] = DISABLED
start_pause_Button['text'] = '暂停点名'
threading.Thread(target=roll_call_begins).start()
def view_colors():
window_view_colors = Tk()
window_view_colors.title("随机点名——部分颜色代码")
try:
window_view_colors.iconbitmap('.\\program\\image\\RandomRollCall.ico')
except:
pass
i = 0
colcut = 5
for color in colors.split('\n'):
sp = color.split(' ')
try:
Label(window_view_colors,text=color, bg=sp[1]).grid(row=int(i/colcut),column=i%colcut, sticky=W+E+N+S)
except :
print('err',color)
Label(window_view_colors,text='ERR'+color).grid(row=int(i/colcut),column=i%colcut, sticky=W+E+N+S)
i += 1
window_view_colors.mainloop()
def set_up():
'''显示设置窗口'''
global window
global wset_up
global file
global background
global buttonbg
global f21# 方便保存时更改背景色
global f31# 方便保存时更改背景色(用来测试)
global animation
animation = False
file = data['file']
background = data['background']
window.destroy()# 销毁主窗口
wset_up=Tk()# 设置窗口
wset_up.title("随机点名——设置")
try:# 尝试打开设置图标
wset_up.iconbitmap('.\\program\\image\\RandomRollCall.ico')
except:
pass
global vname_file
global vbackground
global vbuttonbg
vname_file = StringVar()
vbackground = StringVar()
vbuttonbg = StringVar()
vname_file.set(file)
vbackground.set(data['background'])
vbuttonbg.set(data['buttonbg'])
win = Frame(wset_up,
)
win.pack()
f1 = Frame(win,
)
f1.pack(fill=X,padx=5,pady=5)
l1 = Label(f1,
text="姓名文件:",
font=('宋体', 12),
)
l1.pack(side=LEFT) # 固定窗口位置
ename_file = Entry(f1,
textvariable=vname_file,
width=30,
)
ename_file.pack(side=LEFT)
bchoice = Button(f1,
text="选择\n文件",
font=('宋体', 10),
command=choice,
)
bchoice.pack(side=RIGHT)
f2 = Frame(win,
)
f2.pack(fill=X,padx=5,pady=5)
l2 = Label(f2,
text="背景颜色:",
font=('宋体', 12),
)
l2.pack(side=LEFT) # 固定窗口位置
change_background_color_CMD = wset_up.register(change_background_color) # 包装起来
ebackground = Entry(f2,
textvariable=vbackground,#可变本文
width=10,
validate='key', # 启用验证,当输入框被编辑时验证
validatecommand=(change_background_color_CMD, '%P'),
)
ebackground.pack(side=LEFT)
f21 = Frame(f2,
bg = data['background'],
width=135,
height=25,
)
f21.pack(side=LEFT)
colorchooser_background_color_Button = Button(f2,
text="选择",
command = colorchooser_change_background_color,
font=('宋体', 12),
)
colorchooser_background_color_Button.pack(side=LEFT)
f3 = Frame(win,
)
f3.pack(fill=X,padx=5,pady=5)
buttonbg_color_Label = Label(f3,
text="按钮颜色:",
font=('宋体', 12),
)
buttonbg_color_Label.pack(side=LEFT) # 固定窗口位置
change_buttonbg_color_CMD = wset_up.register(change_buttonbg_color) # 包装起来
ebuttonbg = Entry(f3,
textvariable=vbuttonbg,#可变本文
width=10,
validate='key', # 启用验证,当输入框被编辑时验证
validatecommand=(change_buttonbg_color_CMD, '%P'),
)
ebuttonbg.pack(side=LEFT)
f31 = Frame(f3,
bg = data['buttonbg'],
width=135,
height=25,
)
f31.pack(side=LEFT)
colorchooser_buttonbg_color_Button = Button(f3,
text="选择",
command = colorchooser_change_buttonbg_color,
font=('宋体', 12),
)
colorchooser_buttonbg_color_Button.pack(side=LEFT)
f4 = Frame(win,
)
f4.pack(fill=X,padx=5,pady=5)
global var__topmost_Checkbutton
view_colors_Button = Button(f4,
text="查看部分颜色代码",
font=('宋体', 12),
command=view_colors,
)
view_colors_Button.pack(padx=0,pady=0,side=RIGHT) # fill=X,
font_size_Frame = Frame(win)
font_size_Frame.pack()
font_size_Label = Label(font_size_Frame,
text="字体\n大小",
font=('宋体', 12),
)
font_size_Label.pack(side=LEFT) # 固定窗口位置
global var_font_size_Scale
var_font_size_Scale = StringVar()
font_size_Scale = Scale(font_size_Frame,# 滑块
from_ = 1,
to = 335,
orient = HORIZONTAL,
resolution=1,
tickinterval = 50,
length = 300,
variable = var_font_size_Scale,
)
font_size_Scale.pack(side=LEFT) # 固定滑块位置
var_font_size_Scale.set(str(data['font_size']))
fb = Frame(win,
)
fb.pack(padx=5,pady=5)
bsave_changes = Button(fb,
text="保存",
font=('宋体', 14),
command=save_changes,
)
bsave_changes.pack(side=LEFT,padx=5,pady=5)
bcancel = Button(fb,
text="取消",
font=('宋体', 14),
command=wset_up.destroy,
)
bcancel.pack(side=LEFT,padx=5,pady=5)
brestore_default = Button(fb,
text="恢复默认",
font=('宋体', 14),
command=restore_default,
)
brestore_default.pack(side=LEFT,padx=5,pady=5)
wset_up.mainloop() #循环消息,让窗口活起来
root()
def root():
'''显示主窗口'''
global window
window=Tk()
window.title("随机点名V%i.%i.%i.%i"%tuple([data['verson'][i] for i in range(4)]))
try:
window.iconbitmap('.\\program\\image\\RandomRollCall.ico')
except:
pass
global var_no_repeat_roll_call
var_no_repeat_roll_call = IntVar()
var_no_repeat_roll_call.set(0)
win = Frame(window,
bg = data['background'],
)
win.pack(fill=X)
f1 = Frame(win,
bg = data['background'],
)
f1.pack(fill=X)
bset_up = Button(f1,
text="设置",
bg = data['buttonbg'],
font=('宋体', 12),
command=set_up,
)
bset_up.pack(side=LEFT)
no_repeat_roll_call_Checkbutton = Checkbutton(f1,
bg = data['background'],
text='不重复点名',
variable=var_no_repeat_roll_call,
onvalue=1,
offvalue=0,
font=('宋体', 12),
command=no_repeat_roll_call,
)
no_repeat_roll_call_Checkbutton.pack(side=LEFT)
global reset_Button
reset_Button = Button(f1,
text="复位",
bg=data['buttonbg'],
font=('宋体', 12),
command=reset,
)
reset_Button.pack(side=LEFT)
reset_Button.pack_forget()
global remaining_names_Lable
remaining_names_Lable = Label(f1,
text='剩余姓名:'+str(len(names)-len(havenames))+'/'+str(len(names)),
bg=data['background'],
font=('宋体', 12),
)
remaining_names_Lable.pack(side=LEFT) # 固定窗口位置
remaining_names_Lable.pack_forget()
f2 = Frame(win,
bg = data['background'],
)
f2.pack()
global lname
lname = Label(f2,
text='',
bg = data['background'],
font=('黑体', data['font_size']),
)
lname.pack() # 固定窗口位置
global random_roll_call_Button
random_roll_call_Button = Button(f2,
text="随机点名",
bg = data['buttonbg'],
font=('宋体', 20),
command=random_roll_call,
)
random_roll_call_Button.pack()
global start_pause_Button
start_pause_Button = Button(f2,
text="开始点名",
bg = data['buttonbg'],
font=('宋体', 20),
command=start_pause,
)
start_pause_Button.pack()
f3 = Frame(win,
bg = data['background'],
)
f3.pack(fill=X) # 固定窗口位置
clearing_Button = Button(f3,
text="清零",
bg = data['buttonbg'],
font=('宋体', 12),
command=clearing,
)
clearing_Button.pack(side=LEFT)
global cumulative_Label
cumulative_Label = Label(f3,
text="累计抽取人数:"+str(data['cumulative']),
bg = data['background'],
font=('宋体', 12),
)
cumulative_Label.pack(side=LEFT) # 固定窗口位置
lnone = Label(f3,
text=" ",
bg = data['background'],
font=('宋体', 12),
)
lnone.pack(side=LEFT) # 固定窗口位置
window.wm_attributes("-alpha", data['-alpha'])
window.wm_attributes("-topmost", data['-topmost']) # 永远处于顶层
window.mainloop() #循环消息,让窗口活起来
def main():
global data
'程序入口函数'
data = read_data(data, json_data_file)
data = change_data(data, data_default)
data['verson'] = data_default['verson'] # 保持版本号为当前版本号
data['program_path'] = sys.argv[0] # 更新程序路径
data['program_name'] = data_default['program_name'] # 保持程序名为当前程序名
first_read()
root()
data['time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
save_data(data, json_data_file)
if __name__ == '__main__':
try:
data = read_data(data, json_data_file)
data = change_data(data, data_default)
data['verson'] = data_default['verson'] # 保持版本号为当前版本号
data['program_path'] = sys.argv[0] # 更新程序路径
data['program_name'] = data_default['program_name'] # 保持程序名为当前程序名
first_read()
root()# 显示主窗口
data['time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
save_data(data, json_data_file)
except:
messagebox.showerror(
title = '程序出错!',
message='程序出现未知错误!\n%s' % (format_exc() ))
|
|