Compare commits

...

6 Commits
v1.1 ... main

2 changed files with 100 additions and 29 deletions

65
auto-py-to-exe.json Normal file

@ -0,0 +1,65 @@
{
"version": "auto-py-to-exe-configuration_v1",
"pyinstallerOptions": [
{
"optionDest": "noconfirm",
"value": true
},
{
"optionDest": "filenames",
"value": "J:/Projects/LuckyDraw/main.py"
},
{
"optionDest": "onefile",
"value": true
},
{
"optionDest": "console",
"value": false
},
{
"optionDest": "icon_file",
"value": "J:/Projects/LuckyDraw/icon.ico"
},
{
"optionDest": "clean_build",
"value": false
},
{
"optionDest": "strip",
"value": false
},
{
"optionDest": "noupx",
"value": false
},
{
"optionDest": "disable_windowed_traceback",
"value": false
},
{
"optionDest": "uac_admin",
"value": false
},
{
"optionDest": "uac_uiaccess",
"value": false
},
{
"optionDest": "argv_emulation",
"value": false
},
{
"optionDest": "bootloader_ignore_signals",
"value": false
},
{
"optionDest": "datas",
"value": "J:/Projects/LuckyDraw/icon.png;."
}
],
"nonPyinstallerOptions": {
"increaseRecursionLimit": true,
"manualArguments": ""
}
}

64
main.py

@ -4,6 +4,8 @@ import random
import winreg import winreg
from datetime import datetime from datetime import datetime
import os import os
import pkg_resources
import base64
# 注册表路径 # 注册表路径
REGISTRY_PATH = r"Software\StudentIDDraw" REGISTRY_PATH = r"Software\StudentIDDraw"
@ -12,13 +14,13 @@ REGISTRY_PATH = r"Software\StudentIDDraw"
DEFAULT_ALLOW_REPEAT = False DEFAULT_ALLOW_REPEAT = False
DEFAULT_MIN_ID = 1 DEFAULT_MIN_ID = 1
DEFAULT_MAX_ID = 45 DEFAULT_MAX_ID = 45
PASSWORD = "Admin@123" PASSWORD = "admin000"
selected_ids = [] selected_ids = []
temp_selected_ids = []
is_running = False is_running = False
job = None job = None
# 注册表工具函数 # 注册表工具函数
def set_registry_value(value_name, value, value_type=winreg.REG_SZ): def set_registry_value(value_name, value, value_type=winreg.REG_SZ):
try: try:
@ -27,7 +29,6 @@ def set_registry_value(value_name, value, value_type=winreg.REG_SZ):
except WindowsError as e: except WindowsError as e:
print(f"Error setting registry value: {e}") print(f"Error setting registry value: {e}")
def get_registry_value(value_name, default_value): def get_registry_value(value_name, default_value):
try: try:
with winreg.OpenKey( with winreg.OpenKey(
@ -38,7 +39,6 @@ def get_registry_value(value_name, default_value):
except WindowsError: except WindowsError:
return default_value return default_value
def delete_registry_value(value_name): def delete_registry_value(value_name):
try: try:
with winreg.OpenKey( with winreg.OpenKey(
@ -48,10 +48,9 @@ def delete_registry_value(value_name):
except WindowsError as e: except WindowsError as e:
print(f"Error deleting registry value: {e}") print(f"Error deleting registry value: {e}")
# 加载已抽取的学号 # 加载已抽取的学号
def load_selected_ids(): def load_selected_ids():
global selected_ids global selected_ids, temp_selected_ids
selected_ids_str = get_registry_value("SelectedIDs", "") selected_ids_str = get_registry_value("SelectedIDs", "")
if selected_ids_str: if selected_ids_str:
selected_ids = [] selected_ids = []
@ -69,9 +68,9 @@ def load_selected_ids():
selected_ids = [] selected_ids = []
else: else:
selected_ids = [] selected_ids = []
temp_selected_ids = list(selected_ids)
return selected_ids return selected_ids
# 保存已抽取的学号 # 保存已抽取的学号
def save_selected_ids(): def save_selected_ids():
global selected_ids global selected_ids
@ -83,7 +82,6 @@ def save_selected_ids():
) )
set_registry_value("SelectedIDs", selected_ids_str) set_registry_value("SelectedIDs", selected_ids_str)
# 加载设置 # 加载设置
def load_settings(): def load_settings():
allow_repeat = ( allow_repeat = (
@ -93,14 +91,12 @@ def load_settings():
max_id = int(get_registry_value("MaxID", str(DEFAULT_MAX_ID))) max_id = int(get_registry_value("MaxID", str(DEFAULT_MAX_ID)))
return allow_repeat, min_id, max_id return allow_repeat, min_id, max_id
# 保存设置 # 保存设置
def save_settings(allow_repeat, min_id, max_id): def save_settings(allow_repeat, min_id, max_id):
set_registry_value("AllowRepeat", str(allow_repeat)) set_registry_value("AllowRepeat", str(allow_repeat))
set_registry_value("MinID", str(min_id)) set_registry_value("MinID", str(min_id))
set_registry_value("MaxID", str(max_id)) set_registry_value("MaxID", str(max_id))
# 生成随机的学号 # 生成随机的学号
def generate_random_id(selected_ids, allow_repeat, min_id, max_id): def generate_random_id(selected_ids, allow_repeat, min_id, max_id):
if not allow_repeat: if not allow_repeat:
@ -118,20 +114,20 @@ def update_history_list():
global history_list global history_list
if history_list: if history_list:
history_list.delete(0, tk.END) history_list.delete(0, tk.END)
for id, timestamp in selected_ids: for id, timestamp in temp_selected_ids:
history_list.insert(tk.END, f"{id} ({timestamp})") history_list.insert(tk.END, f"{id} ({timestamp})")
# 每隔 5 毫秒更新一次显示的随机学号 # 每隔 5 毫秒更新一次显示的随机学号
def update_number(allow_repeat, min_id, max_id): def update_number(allow_repeat, min_id, max_id):
global job global job
if is_running: if is_running:
random_id = generate_random_id(selected_ids, allow_repeat, min_id, max_id) random_id = generate_random_id(temp_selected_ids, allow_repeat, min_id, max_id)
label.config(text=str(random_id)) label.config(text=str(random_id))
job = root.after(5, update_number, allow_repeat, min_id, max_id) job = root.after(5, update_number, allow_repeat, min_id, max_id)
# 抽取学号按钮点击事件处理函数 # 抽取学号按钮点击事件处理函数
def draw_student_id(): def draw_student_id():
global is_running, job, selected_ids global is_running, job, selected_ids, temp_selected_ids
allow_repeat, min_id, max_id = load_settings() allow_repeat, min_id, max_id = load_settings()
if is_running: if is_running:
@ -140,6 +136,7 @@ def draw_student_id():
id = label.cget("text") id = label.cget("text")
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
selected_ids.append((str(id), timestamp)) selected_ids.append((str(id), timestamp))
temp_selected_ids.append((str(id), timestamp))
save_selected_ids() save_selected_ids()
if settings_window: if settings_window:
update_history_list() update_history_list()
@ -151,7 +148,6 @@ def draw_student_id():
button.config(text="停止") button.config(text="停止")
update_number(allow_repeat, min_id, max_id) update_number(allow_repeat, min_id, max_id)
# 设置按钮点击事件处理函数 # 设置按钮点击事件处理函数
def open_settings(): def open_settings():
global settings_window global settings_window
@ -189,46 +185,48 @@ def open_settings():
update_history_list() update_history_list()
def add_id(): def add_id():
new_id = simpledialog.askstring("新增学号", "请输入新的学号:") new_id = simpledialog.askstring("新增学号", "请输入新的学号:", parent=settings_window)
if new_id: if new_id:
if new_id.isdigit(): if new_id.isdigit():
new_id = int(new_id) new_id = int(new_id)
if min_id <= new_id <= max_id: if min_id <= new_id <= max_id:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
selected_ids.append((str(new_id), timestamp)) temp_selected_ids.append((str(new_id), timestamp))
update_history_list() update_history_list()
else: else:
messagebox.showerror("错误", f"学号必须在 {min_id}{max_id} 之间") messagebox.showerror("错误", f"学号必须在 {min_id}{max_id} 之间")
else: else:
messagebox.showerror("错误", "请输入有效的学号") messagebox.showerror("错误", "请输入有效的学号")
settings_window.focus_force()
def delete_id(): def delete_id():
selected = history_list.curselection() selected = history_list.curselection()
if selected: if selected:
index = selected[0] index = selected[0]
selected_ids.pop(index) temp_selected_ids.pop(index)
update_history_list() update_history_list()
if index < len(selected_ids): if index < len(temp_selected_ids):
history_list.select_set(index) history_list.select_set(index)
elif selected_ids: elif temp_selected_ids:
history_list.select_set(index - 1) history_list.select_set(index - 1)
else: else:
messagebox.showerror("错误", "请选择一个学号进行删除") messagebox.showerror("错误", "请选择一个学号进行删除")
settings_window.focus_force()
def edit_id(): def edit_id():
selected = history_list.curselection() selected = history_list.curselection()
if selected: if selected:
index = selected[0] index = selected[0]
current_id, _ = selected_ids[index] current_id, _ = temp_selected_ids[index]
new_id = simpledialog.askstring( new_id = simpledialog.askstring(
"修改学号", "请输入新的学号:", initialvalue=str(current_id) "修改学号", "请输入新的学号:", initialvalue=str(current_id), parent=settings_window
) )
if new_id: if new_id:
if new_id.isdigit(): if new_id.isdigit():
new_id = int(new_id) new_id = int(new_id)
if min_id <= new_id <= max_id: if min_id <= new_id <= max_id:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
selected_ids[index] = (str(new_id), timestamp) temp_selected_ids[index] = (str(new_id), timestamp)
update_history_list() update_history_list()
history_list.select_set(index) history_list.select_set(index)
else: else:
@ -237,10 +235,11 @@ def open_settings():
messagebox.showerror("错误", "请输入有效的学号") messagebox.showerror("错误", "请输入有效的学号")
else: else:
messagebox.showerror("错误", "请选择一个学号进行修改") messagebox.showerror("错误", "请选择一个学号进行修改")
settings_window.focus_force()
def clear_all_ids(): def clear_all_ids():
global selected_ids global temp_selected_ids
selected_ids = [] temp_selected_ids = []
update_history_list() update_history_list()
tk.Button(settings_window, text="新增记录", font=("宋体", 10), command=add_id).grid( tk.Button(settings_window, text="新增记录", font=("宋体", 10), command=add_id).grid(
@ -274,8 +273,10 @@ def open_settings():
) )
def save_changes(): def save_changes():
entered_password = simpledialog.askstring("密码", "请输入密码:", show="*") entered_password = simpledialog.askstring("密码", "请输入密码:", parent=settings_window, show="*")
if entered_password == PASSWORD: if entered_password == PASSWORD:
global selected_ids
selected_ids = list(temp_selected_ids)
save_settings( save_settings(
allow_repeat_var.get(), int(min_id_var.get()), int(max_id_var.get()) allow_repeat_var.get(), int(min_id_var.get()), int(max_id_var.get())
) )
@ -284,6 +285,7 @@ def open_settings():
close_settings_window() close_settings_window()
else: else:
messagebox.showerror("错误", "密码错误") messagebox.showerror("错误", "密码错误")
settings_window.focus_force()
tk.Button(settings_window, text="保存", font=("宋体", 10), command=save_changes).grid( tk.Button(settings_window, text="保存", font=("宋体", 10), command=save_changes).grid(
row=8, column=0, columnspan=2, padx=5, pady=20, sticky="ew" row=8, column=0, columnspan=2, padx=5, pady=20, sticky="ew"
@ -299,24 +301,28 @@ def open_settings():
settings_window.protocol("WM_DELETE_WINDOW", close_settings_window) settings_window.protocol("WM_DELETE_WINDOW", close_settings_window)
def close_settings_window(): def close_settings_window():
global settings_window global settings_window
settings_window.destroy() settings_window.destroy()
settings_window = None settings_window = None
def get_icon_data():
icon_path = pkg_resources.resource_filename(__name__, 'icon.png')
with open(icon_path, 'rb') as icon_file:
return base64.b64encode(icon_file.read())
# 初始化全局变量 # 初始化全局变量
selected_ids = load_selected_ids() selected_ids = load_selected_ids()
settings_window = None settings_window = None
history_list = None history_list = None
icon_data = get_icon_data()
# 创建主窗口 # 创建主窗口
root = tk.Tk() root = tk.Tk()
root.title("随机抽号机") root.title("随机抽号机")
root.attributes("-topmost", 1) root.attributes("-topmost", 1)
icon_path = os.path.join("icon.png") icon_image = tk.PhotoImage(data=icon_data)
icon_image = tk.PhotoImage(file=icon_path)
root.iconphoto(True, icon_image) root.iconphoto(True, icon_image)
# 创建标签,用于显示抽取的学号 # 创建标签,用于显示抽取的学号
@ -334,7 +340,7 @@ settings_button.pack(pady=10)
# 创建多行标签,用于显示信息,内容居中显示 # 创建多行标签,用于显示信息,内容居中显示
info_label = tk.Label( info_label = tk.Label(
root, root,
text="LuckyDraw v1.1 2024/06/22\nCopyright 2024 earthjasonlin\n保留所有权利。\n本程序仅作为交流学习使用", text="LuckyDraw v1.2 2024/06/22\nCopyright 2024 earthjasonlin\n保留所有权利。\n本程序仅作为交流学习使用",
font=("宋体", 10), font=("宋体", 10),
justify="center", justify="center",
anchor="center", anchor="center",