使用Tkinter开发2024年包头市“工匠杯”CAD机械设计比赛抽签系统

 引言

在各类比赛和活动中,抽签、中奖、分组、配对等操作常常是必不可少的步骤。为了提高操作的效率和减少人为错误,开发一个基于Python和Tkinter的抽签系统可以大大简化这些流程。这篇博文将介绍如何使用Tkinter构建一个用于“2024年包头市‘工匠杯’CAD机械设计比赛”的抽签系统,支持多种模式,包括抽签模式、中奖模式、分组模式和配对模式。

 项目介绍

该抽签系统支持以下几种模式:

1. **抽签模式**:随机从导入的名单中选择一位参与者,并为其分配一个随机号码。

2. **中奖模式**:从导入名单中选择若干名中奖者,逐个显示中奖结果。

3. **分组模式**:根据导入名单,将所有参与者随机分配到指定的组别中。

4. **配对模式**:从两个导入的名单中,随机配对,形成对应的左右名单配对。

 主要功能

- **导入Excel名单**:支持导入Excel格式的名单,并根据不同模式执行相应的操作。

- **随机抽取**:在抽签模式和配对模式下,支持随机抽取名单或配对。

- **滚动显示效果**:在抽签和配对模式下,系统会模拟滚动效果,直到用户手动停止,显示最终结果。

- **历史记录和导出**:所有结果都实时展示在界面中,并且可以导出到Excel文件中保存。

 代码实现

import tkinter as tk

from tkinter import filedialog, messagebox

import pandas as pd

import random

 

class RaffleApp:

    def __init__(self, root):

        self.root = root

        self.root.title("2024 年包头市“工匠杯”CAD 机械设计职工职业技能比赛 抽签系统")

        self.mode = "抽签模式" # 初始为抽签模式

        self.names = []

        self.left_names = [] # 配对模式中的左名单

        self.right_names = [] # 配对模式中的右名单

        self.results = [] # 用于存储抽签/中奖/分组/配对结果

        self.groups = {} # 分组模式下的组

        self.rolling_number = None # 滚动显示的数字

        self.is_rolling = False # 控制数字滚动的状态

        self.current_name = "" # 当前抽签人

        self.selected_numbers = set() # 已经抽取的数字

        self.winner_queue = [] # 中奖人列表,用于中奖模式的逐个展示

        self.current_left = "" # 当前配对模式中的左名单

        self.current_right = "" # 当前配对模式中的右名单

        self.create_widgets()

 

    def create_widgets(self):

        # 主框架

        self.main_frame = tk.Frame(self.root, padx=20, pady=20)

        self.main_frame.pack(fill=tk.BOTH, expand=True)

 

        # 标题

        self.title_label = tk.Label(self.main_frame, text="2024 年包头市“工匠杯”CAD 机械设计比赛 抽签系统",

                                    font=("Arial", 38), padx=10, pady=10)

        self.title_label.pack(pady=(0, 20))

 

        # 模式切换按钮

        self.mode_frame = tk.Frame(self.main_frame)

        self.mode_frame.pack(pady=(0, 20))

 

        self.raffle_mode_button = tk.Button(self.mode_frame, text="抽签模式", command=self.set_raffle_mode)

        self.raffle_mode_button.pack(side=tk.LEFT, padx=10)

 

        self.prize_mode_button = tk.Button(self.mode_frame, text="中奖模式", command=self.set_prize_mode)

        self.prize_mode_button.pack(side=tk.LEFT, padx=10)

 

        self.group_mode_button = tk.Button(self.mode_frame, text="分组模式", command=self.set_group_mode)

        self.group_mode_button.pack(side=tk.LEFT, padx=10)

 

        self.pair_mode_button = tk.Button(self.mode_frame, text="配对模式", command=self.set_pair_mode)

        self.pair_mode_button.pack(side=tk.LEFT, padx=10)

 

        # 主操作区域

        self.operation_frame = tk.Frame(self.main_frame)

        self.operation_frame.pack()

 

        # 导入按钮

        self.load_button = tk.Button(self.operation_frame, text="导入名单", command=self.load_names)

        self.load_button.pack(side=tk.LEFT, padx=5)

 

        # 开始按钮

        self.start_button = tk.Button(self.operation_frame, text="开始", command=self.start_action, state=tk.DISABLED)

        self.start_button.pack(side=tk.LEFT, padx=5)

 

        # 停止按钮 (用于抽签和配对模式)

        self.stop_button = tk.Button(self.operation_frame, text="停止", command=self.stop_action, state=tk.DISABLED)

        self.stop_button.pack(side=tk.LEFT, padx=5)

 

        # 导出按钮,启用状态

        self.export_button = tk.Button(self.operation_frame, text="导出结果", command=self.export_results, state=tk.NORMAL)

        self.export_button.pack(side=tk.LEFT, padx=5)

 

        # 显示当前结果的标签

        self.result_label = tk.Label(self.main_frame, text="", font=("Arial", 50))

        self.result_label.pack(pady=(20, 10))

 

        # 历史记录框

        self.history_label = tk.Label(self.main_frame, text="历史记录:", font=("Arial", 18))

        self.history_label.pack(pady=(10, 5))

        self.history_listbox = tk.Listbox(self.main_frame, width=200, height=100)

        self.history_listbox.pack(pady=(0, 20))

 

        self.set_raffle_mode() # 默认初始化为抽签模式

 

    def set_raffle_mode(self):

        self.mode = "抽签模式"

        self.stop_button.pack(side=tk.LEFT, padx=5) # 显示停止按钮

        self.result_label.config(text="") # 清空结果显示

        self.history_listbox.delete(0, tk.END)

        self.update_buttons()

 

    def set_prize_mode(self):

        self.mode = "中奖模式"

        self.stop_button.pack_forget() # 隐藏停止按钮

        self.result_label.config(text="") # 清空结果显示

        self.history_listbox.delete(0, tk.END)

        self.update_buttons()

 

    def set_group_mode(self):

        self.mode = "分组模式"

        self.stop_button.pack_forget() # 隐藏停止按钮

        self.result_label.config(text="") # 清空结果显示

        self.history_listbox.delete(0, tk.END)

        self.update_buttons()

 

    def set_pair_mode(self):

        self.mode = "配对模式"

        self.stop_button.pack(side=tk.LEFT, padx=5)

        self.result_label.config(text="") # 清空结果显示

        self.history_listbox.delete(0, tk.END)

        self.update_buttons()

 

    def update_buttons(self):

        if (self.names or (self.left_names and self.right_names)):

            self.start_button.config(state=tk.NORMAL)

        else:

            self.start_button.config(state=tk.DISABLED)

 

    def load_names(self):

        if self.mode == "配对模式":

            # Load left and right lists for pairing mode

            left_file = filedialog.askopenfilename(title="导入左名单", filetypes=[("Excel Files", "*.xlsx")])

            right_file = filedialog.askopenfilename(title="导入右名单", filetypes=[("Excel Files", "*.xlsx")])

            if left_file and right_file:

                left_df = pd.read_excel(left_file)

                right_df = pd.read_excel(right_file)

                self.left_names = left_df.iloc[:, 0].dropna().tolist()

                self.right_names = right_df.iloc[:, 0].dropna().tolist()

                self.result_label.config(text=f"已导入左名单 {len(self.left_names)} 人, 右名单 {len(self.right_names)} 人")

                self.update_buttons()

        else:

            # Load names for other modes

            file_path = filedialog.askopenfilename(filetypes=[("Excel Files", "*.xlsx")])

            if file_path:

                df = pd.read_excel(file_path)

                self.names = df.iloc[:, 0].dropna().tolist()

                self.result_label.config(text=f"已导入 {len(self.names)} 人员")

                self.update_buttons()

 

    def start_action(self):

        if self.mode == "抽签模式":

            self.start_raffle()

        elif self.mode == "中奖模式":

            self.start_prize_draw()

        elif self.mode == "分组模式":

            self.start_grouping()

        elif self.mode == "配对模式":

            self.start_pairing()

 

    def stop_action(self):

        if self.mode == "抽签模式":

            self.stop_raffle()

        elif self.mode == "配对模式":

            self.stop_pairing()

 

    def start_raffle(self):

        if self.names:

            self.current_name = random.choice(self.names)

            self.result_label.config(text=f"当前抽签人: {self.current_name} 正在抽取数字...")

            self.names.remove(self.current_name)

            self.is_rolling = True # 开始滚动

            self.roll_number()

            self.start_button.config(state=tk.DISABLED)

            self.stop_button.config(state=tk.NORMAL)

 

    def roll_number(self):

        if self.is_rolling:

            available_numbers = list(set(range(1, len(self.results) + len(self.names) + 1)) - self.selected_numbers)

            if available_numbers:

                self.rolling_number = random.choice(available_numbers)

                self.result_label.config(text=f"{self.current_name} 正在抽取: {self.rolling_number}")

                self.root.after(100, self.roll_number)

 

    def stop_raffle(self):

        self.is_rolling = False

        self.selected_numbers.add(self.rolling_number)

        self.result_label.config(text=f"{self.current_name} 的抽签结果: {self.rolling_number}")

        self.history_listbox.insert(tk.END, f"{self.current_name}: {self.rolling_number}")

        self.results.append((self.current_name, self.rolling_number))

        self.stop_button.config(state=tk.DISABLED)

        self.update_buttons()

 

    def start_pairing(self):

        if self.left_names and self.right_names:

            self.is_rolling = True

            self.roll_pair()

            self.start_button.config(state=tk.DISABLED)

            self.stop_button.config(state=tk.NORMAL)

 

    def roll_pair(self):

        if self.is_rolling and self.left_names and self.right_names:

            self.current_left = random.choice(self.left_names)

            self.current_right = random.choice(self.right_names)

            self.result_label.config(text=f"配对中: {self.current_left} 和 {self.current_right}")

            self.root.after(100, self.roll_pair)

 

    def stop_pairing(self):

        self.is_rolling = False

        self.result_label.config(text=f"配对结果: {self.current_left} 和 {self.current_right}")

        self.history_listbox.insert(tk.END, f"{self.current_left} 和 {self.current_right}")

        self.results.append((self.current_left, self.current_right))

        self.left_names.remove(self.current_left)

        self.right_names.remove(self.current_right)

        self.stop_button.config(state=tk.DISABLED)

        if not self.left_names or not self.right_names:

            self.start_button.config(state=tk.DISABLED)

        self.update_buttons()

 

    def export_results(self):

        file_path = filedialog.asksaveasfilename(defaultextension=".xlsx", filetypes=[("Excel Files", "*.xlsx")])

        if file_path:

            if self.mode == "配对模式":

                df = pd.DataFrame(self.results, columns=["左名单", "右名单"])

            else:

                df = pd.DataFrame(self.results, columns=["姓名", "抽签结果"])

            df.to_excel(file_path, index=False)

            messagebox.showinfo("导出成功", "结果已成功导出到 Excel 文件。")

 

if __name__ == "__main__":

    root = tk.Tk()

    app = RaffleApp(root)

    root.mainloop()

总结

通过这个抽签系统,我们可以轻松实现多个比赛流程的自动化管理,包括抽签、中奖、分组以及配对操作。代码的可扩展性也非常好,未来可以进一步添加更多功能,例如自定义分组策略、自动存档等功能。这是一个简单而实用的比赛管理工具,使用Python的Tkinter框架开发,可以为比赛组织者带来很大的便利。11f4b631e589445dafc2e51111d077ce.jpg

 453eed54a4c0453d95f74dba75492e74.jpg 587377939c134a87be1feece6cc353a4.jpg

 

 

后续改进

未来可以考虑的改进:

1. **用户界面的优化**:提升交互体验。

2. **更多的模式支持**:例如多人配对、复杂分组策略等。

3. **抽签动画效果**:加入更炫酷的视觉效果。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值