当前位置:首页 » 《随便一记》 » 正文

Python-开发运动会计分管理软件

29 人参与  2024年12月06日 08:01  分类 : 《随便一记》  评论

点击全文阅读


PYTHON-开发运动会计分管理软件

项目概述

1. 软件功能

我们的运动会计分管理软件具有以下功能:

添加运动员:提供接口让用户输入运动员的基本信息,包括分组、姓名、名次。管理分组:支持创建、修改和删除运动员分组,方便组织和查看。得分计算:根据运动员名次自动计算得分,并在用户界面中更新。查看总分:统计所有运动员的总分、平均分、最高分和最低分,并支持分组汇总。数据导出:允许用户将所有运动员信息导出为 CSV 文件,便于存档和后续使用。切换破纪录状态:通过右键菜单允许用户方便地切换运动员的破纪录状态,影响得分计算。

2. 技术栈

本项目所需的技术栈包括:

Python:作为编程语言实现逻辑和数据处理。tkinter:构建图形用户界面,快速开发桌面应用。CSV模块:用于处理数据导出与导入的标准库。

3. 软件开发环境

开发此软件时,需确保您的计算机上安装了 Python(建议使用 Python 3.7 及以上版本)。同时,我们使用的 tkinter 库是 Python 的标准库,不需要单独安装。CSV模块也是Python自带的模块,您可以直接使用。

安装与基础设置

安装 Python

前往 Python 官网 下载并安装适合您操作系统的版本。请确保勾选“Add Python to PATH”的选项。

创建项目文件夹

在您的计算机上创建一个新的文件夹,命名为 ScoreManagementApp,在其中创建一个文件 score_app.py,并在里面编写代码。

环境配置

在终端中使用 pip 安装所需的第三方库(如有需要)。本项目不依赖于外部库,直接使用tkintercsv标准库。

开发步骤详解

1. 数据结构设计

通过使用数据类 (dataclass) 来定义运动员的信息结构,使得数据的管理和访问更加方便。

from dataclasses import dataclass@dataclassclass Athlete:    group: str    name: str    rank: int    score: int    is_record: bool = False

上述代码简洁地定义了运动员的各种属性,包括其所属分组、姓名、名次、得分和破纪录状态。使用数据类的好处是可以更直观地管理运动员信息,并提升代码的可读性。

2. 创建主应用程序类 ScoreApp

以下是实现 ScoreApp 类的基本框架和关键功能。该类负责所有界面组件的管理以及实现各项业务逻辑。

import tkinter as tkfrom tkinter import ttk, messagebox, filedialog, Menu, OptionMenu, StringVarimport csvclass ScoreApp:    def __init__(self, root):        self.root = root        self.root.title("运动会计分管理软件")        # 初始化名次和分数对应关系        self.rank_to_score = {1: 9, 2: 7, 3: 6, 4: 5, 5: 4, 6: 3, 7: 2, 8: 1}        # 可用分组        self.available_groups = {"组A"}        # 表格呈现运动员信息        self.tree = ttk.Treeview(root, columns=("分组", "姓名", "名次", "分数", "破纪录"), show='headings')        self.setup_treeview()        # 控件布局和功能定义        self.setup_controls()        # 初始化运动员列表        self.scores = []        self.group_filter_var = StringVar(root)        self.group_filter_var.set("所有分组")        self.setup_group_selection()    def setup_treeview(self):        """ 设置Treeview组件 """        self.tree.heading("分组", text="分组")        self.tree.heading("姓名", text="姓名")        self.tree.heading("名次", text="名次")        self.tree.heading("分数", text="分数")        self.tree.heading("破纪录", text="破纪录")        for col in ("分组", "姓名", "名次", "分数", "破纪录"):            self.tree.column(col, width=100)        self.tree.grid(row=0, column=0, columnspan=5, padx=10, pady=10)    def setup_controls(self):        """ 创建按钮和控制框 """        tk.Button(self.root, text="添加运动员", command=self.open_add_athlete_dialog).grid(row=1, column=0, padx=5, pady=5)        tk.Button(self.root, text="管理分组", command=self.open_group_management).grid(row=1, column=1, padx=5, pady=5)        tk.Button(self.root, text="查看总分", command=self.view_total_scores).grid(row=1, column=2, padx=5, pady=5)        tk.Button(self.root, text="导出数据", command=self.export_to_csv).grid(row=1, column=3, padx=5, pady=5)        tk.Button(self.root, text="删除选中行", command=self.delete_selected).grid(row=1, column=4, padx=5, pady=5)        tk.Button(self.root, text="设置分数", command=self.open_settings).grid(row=1, column=5, padx=5, pady=5)    def setup_group_selection(self):        """ 设置分组选择下拉框 """        # 分组选择实现略

上述代码展示了如何初始化应用程序的窗口并构建基本元素,比如设置表格(Treeview)和按钮。设计时需要确保用户界面友好,并能方便地访问不同功能。

3. 添加运动员信息

添加运动员的对话框包括必要的输入字段,并在用户确认后将数据录入到列表中。

def open_add_athlete_dialog(self):    """ 打开添加运动员的对话框 """    add_window = tk.Toplevel(self.root)    add_window.title("添加运动员")    tk.Label(add_window, text="分组:").grid(row=0, column=0, padx=10, pady=5)    group_entry = StringVar(add_window)    group_entry.set("选择分组或自定义")    group_menu = OptionMenu(add_window, group_entry, *self.available_groups)    group_menu.grid(row=0, column=1, padx=10, pady=5)    tk.Label(add_window, text="姓名:").grid(row=1, column=0, padx=10, pady=5)    name_entry = tk.Entry(add_window)    name_entry.grid(row=1, column=1, padx=10, pady=5)    tk.Label(add_window, text="名次:").grid(row=2, column=0, padx=10, pady=5)    rank_entry = tk.Entry(add_window)    rank_entry.grid(row=2, column=1, padx=10, pady=5)    tk.Button(add_window, text="确认", command=lambda: self.add_score(group_entry.get(), name_entry.get(), rank_entry.get(), add_window)).grid(row=3, columnspan=3, pady=10)def add_score(self, group, name, rank_str, add_window):    """ 添加运动员信息 """    if group and name and rank_str.isdigit() and int(rank_str) in self.rank_to_score:        rank = int(rank_str)        score = self.rank_to_score[rank]        athlete = Athlete(group, name, rank, score)        self.scores.append(athlete)        self.tree.insert("", "end", values=(athlete.group, athlete.name, athlete.rank, athlete.score, "✔" if athlete.is_record else "✖"))        add_window.destroy()    else:        messagebox.showwarning("输入错误", "请确保所有输入有效!")

open_add_athlete_dialog 方法负责展示添加运动员信息的输入窗口,而 add_score 方法则实现将输入的运动员信息添加到数据结构和界面表格中。输入验证确保数据的有效性,避免无效的输入占用系统资源。

4. 查看总分和数据导出

审核和导出运动员总分也是软件必不可少的功能。我们将通过一个弹出的新窗口展示统计数据,并支持将数据导出为 CSV 格式以备存档。

def view_total_scores(self):    total_window = tk.Toplevel(self.root)    total_window.title("总分")    total_label = tk.Label(total_window, text="所有运动员总分:")    total_label.pack(padx=10, pady=5)    total_score = sum(athlete.score * (2 if athlete.is_record else 1) for athlete in self.scores)    all_scores_label = tk.Label(total_window, text=f"总分: {total_score}")    all_scores_label.pack(padx=10, pady=5)    # 计算和展示平均分、最高分、最低分    average_score = total_score / len(self.scores) if self.scores else 0    highest_score = max(athlete.score for athlete in self.scores) if self.scores else 0    lowest_score = min(athlete.score for athlete in self.scores) if self.scores else 0    stats_label = tk.Label(total_window, text=f"平均分: {average_score:.2f}, 最高分: {highest_score}, 最低分: {lowest_score}")    stats_label.pack(padx=10, pady=5)def export_to_csv(self):    filename = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV files", "*.csv")])    if filename:        with open(filename, mode='w', newline='', encoding='utf-8') as file:            writer = csv.writer(file)            writer.writerow(["分组", "姓名", "名次", "分数", "破纪录"])            for athlete in self.scores:                writer.writerow([athlete.group, athlete.name, athlete.rank, athlete.score, athlete.is_record])        messagebox.showinfo("成功", f"数据已导出到 {filename}")

view_total_scores 方法计算所有运动员的分数,并将其展示在新窗口中,而 export_to_csv 则构建 CSV 文件并保存用户指定的位置。此功能对于后续的数据分析和管理至关重要,帮助用户轻松整理和传递信息。

5. 管理分组和删除运动员

用户需要能够动态地管理运动员组和删除不再需要的运动员记录。以下是相关的实现:

def open_group_management(self):    group_window = tk.Toplevel(self.root)    group_window.title("管理分组")    tk.Label(group_window, text="自定义分组:").grid(row=0, column=0, padx=10, pady=5)    custom_group_entry = tk.Entry(group_window)    custom_group_entry.grid(row=0, column=1, padx=10, pady=5)    tk.Button(group_window, text="添加分组", command=lambda: self.add_custom_group(custom_group_entry.get())).grid(row=0, column=2, padx=10, pady=5)    tk.Label(group_window, text="当前分组:").grid(row=1, column=0, padx=10, pady=5)    current_groups_var = StringVar(value=", ".join(sorted(self.available_groups)))    tk.Entry(group_window, textvariable=current_groups_var, state='readonly').grid(row=1, column=1, padx=10, pady=5)    tk.Label(group_window, text="删除分组:").grid(row=2, column=0, padx=10, pady=5)    delete_group_entry = tk.Entry(group_window)    delete_group_entry.grid(row=2, column=1, padx=10, pady=5)    tk.Button(group_window, text="删除分组", command=lambda: self.delete_custom_group(delete_group_entry.get())).grid(row=2, column=2, padx=10, pady=5)def add_custom_group(self, group_name):    if group_name and group_name not in self.available_groups:        self.available_groups.add(group_name)        self.setup_group_selection()        messagebox.showinfo("成功", f"已添加自定义分组: {group_name}")def delete_selected(self):    selected_item = self.tree.selection()    if selected_item:        for item in selected_item:            index = self.tree.index(item)            self.tree.delete(item)            del self.scores[index]        self.update_displayed_athletes()    else:        messagebox.showwarning("选择错误", "请先选择一行!")

open_group_management 方法启用分组的添加和删除,增强了对运动员的组织能力,而 delete_selected 则允许用户删除选中的运动员记录,使得整体管理变得灵活。

6. 用户交互的多样性

在软件中,右键菜单为用户提供了灵活的操作手段,比如切换运动员的破纪录状态。调用右键菜单的相关实现代码如下:

def show_popup(self, event):    try:        selected = self.tree.identify_row(event.y)        if selected:            self.tree.selection_set(selected)            self.popup_menu.post(event.x_root, event.y_root)    except Exception as e:        print(f"Error showing popup menu: {e}")self.popup_menu = Menu(root, tearoff=0)self.popup_menu.add_command(label="切换破纪录", command=self.toggle_record)

通过实现相应的事件绑定,我们使得软件的交互性更强,更加贴合用户的操作习惯。

7. 代码结构与模块化

在整个应用中,保持良好的代码结构和模块化设计是至关重要的。这不仅能提升代码的可读性,还能帮助团队中的其他开发者快速理解和修改代码。

可以将不同的功能区域分开为不同的模块,例如将与数据存储、数据处理、用户界面等相关的功能分别放入不同的文件中。使用 Python 的模块导入功能来连接这些组件,可以有效管理大型项目,提升维护性。

总结

本篇博客详细介绍了如何使用 Python 的 tkinter 库创建一个运动会计分管理软件。

作为示例为研究GUI和数据结构打下基础

完整源码:

import tkinter as tkfrom tkinter import ttk, simpledialog, messagebox, Menu, OptionMenu, StringVar, filedialogfrom dataclasses import dataclassimport csv# 数据类: 运动员信息@dataclassclass Athlete:    group: str    name: str    rank: int    score: int    is_record: bool = Falseclass ScoreApp:    def __init__(self, root):        self.root = root        self.root.title("运动会计分软件")                # 默认名次与分数对应关系        self.rank_to_score = {            1: 9,            2: 7,            3: 6,            4: 5,            5: 4,            6: 3,            7: 2,            8: 1        }        # 可用分组        self.available_groups = {"组A"}  # 默认分组        # 表格呈现        self.tree = ttk.Treeview(root, columns=("分组", "姓名", "名次", "分数", "破纪录"), show='headings')        self.tree.heading("分组", text="分组")        self.tree.heading("姓名", text="姓名")        self.tree.heading("名次", text="名次")        self.tree.heading("分数", text="分数")        self.tree.heading("破纪录", text="破纪录")                self.tree.column("分组", width=100)        self.tree.column("姓名", width=200)        self.tree.column("名次", width=100)        self.tree.column("分数", width=100)        self.tree.column("破纪录", width=100)        self.tree.grid(row=0, column=0, columnspan=5, padx=10, pady=10)        # 添加按钮        self.add_button = tk.Button(root, text="添加运动员", command=self.open_add_athlete_dialog)        self.add_button.grid(row=1, column=0, padx=5, pady=5)        # 管理分组按钮        self.group_management_button = tk.Button(root, text="管理分组", command=self.open_group_management)        self.group_management_button.grid(row=1, column=1, padx=5, pady=5)        # 查看总分按钮        self.total_button = tk.Button(root, text="查看总分", command=self.view_total_scores)        self.total_button.grid(row=1, column=2, padx=5, pady=5)        # 导出按钮        self.export_button = tk.Button(root, text="导出数据", command=self.export_to_csv)        self.export_button.grid(row=1, column=3, padx=5, pady=5)        # 删除按钮        self.delete_button = tk.Button(root, text="删除选中行", command=self.delete_selected)        self.delete_button.grid(row=1, column=4, padx=5, pady=5)        # 设置按钮        self.settings_button = tk.Button(root, text="设置分数", command=self.open_settings)        self.settings_button.grid(row=1, column=5, padx=5, pady=5)        # 右键菜单        self.popup_menu = Menu(root, tearoff=0)        self.popup_menu.add_command(label="切换破纪录", command=self.toggle_record)        self.popup_menu.add_separator()        # 这里调用 open_group_management        self.popup_menu.add_command(label="设置分组", command=self.open_group_management)        # 绑定右键点击        self.tree.bind("<Button-3>", self.show_popup)        # 运动员信息列表        self.scores = []        # 分组过滤变量        self.group_filter_var = StringVar(root)        self.group_filter_var.set("所有分组")        self.setup_group_selection()    def setup_group_selection(self):        """ 设置和显示分组选择下拉框 """        groups = sorted(self.available_groups) + ["所有分组"]        group_menu = OptionMenu(self.root, self.group_filter_var, *groups, command=self.update_displayed_athletes)        group_menu.grid(row=1, column=6, padx=5, pady=5)    def update_displayed_athletes(self, *args):        """ 根据选择的分组更新显示的运动员 """        self.tree.delete(*self.tree.get_children())        filtered_scores = [athlete for athlete in self.scores if self.group_filter_var.get() in ("所有分组", athlete.group)]        for athlete in filtered_scores:            self.tree.insert("", "end", values=(athlete.group, athlete.name, athlete.rank, athlete.score, "✔" if athlete.is_record else "✖"))    def open_add_athlete_dialog(self):        """ 打开添加运动员的对话框 """        add_window = tk.Toplevel(self.root)        add_window.title("添加运动员")        # 输入字段        tk.Label(add_window, text="分组:").grid(row=0, column=0, padx=10, pady=5)        group_entry = StringVar(add_window)        group_entry.set("选择分组或自定义")        group_menu = OptionMenu(add_window, group_entry, *self.available_groups)        group_menu.grid(row=0, column=1, padx=10, pady=5)        custom_group_entry = tk.Entry(add_window)  # 自定义分组输入        custom_group_entry.grid(row=0, column=2, padx=10, pady=5)        tk.Label(add_window, text="姓名:").grid(row=1, column=0, padx=10, pady=5)        name_entry = tk.Entry(add_window)        name_entry.grid(row=1, column=1, padx=10, pady=5)        tk.Label(add_window, text="名次:").grid(row=2, column=0, padx=10, pady=5)        rank_entry = tk.Entry(add_window)        rank_entry.grid(row=2, column=1, padx=10, pady=5)        # 确认按钮        tk.Button(add_window, text="确认", command=lambda: self.add_score(custom_group_entry.get(), group_entry.get(), name_entry.get(), rank_entry.get(), add_window)).grid(row=3, columnspan=3, pady=10)    def add_score(self, custom_group, group, name, rank_str, add_window):        """ 添加运动员信息 """        group_to_use = custom_group if custom_group else group        if group_to_use and name and rank_str.isdigit() and int(rank_str) in self.rank_to_score:            rank = int(rank_str)            score = self.rank_to_score[rank]            athlete = Athlete(group_to_use, name, rank, score)  # 使用数据类            self.scores.append(athlete)  # 添加运动员            self.tree.insert("", "end", values=(athlete.group, athlete.name, athlete.rank, athlete.score, "✔" if athlete.is_record else "✖"))            add_window.destroy()  # 关闭添加窗口            self.sort_treeview()  # 添加后自动排序            self.available_groups.add(group_to_use)  # 自定义分组添加到集合            self.setup_group_selection()  # 更新分组选择        else:            messagebox.showwarning("输入错误", "请确保所有输入有效!")    def sort_treeview(self):        """ 按照分数从高到低排序 """        sorted_scores = sorted(self.scores, key=lambda x: x.score, reverse=True)        self.tree.delete(*self.tree.get_children())  # 清空当前显示的所有行        # 重新显示排序后的运动员信息        for athlete in sorted_scores:            self.tree.insert("", "end", values=(athlete.group, athlete.name, athlete.rank, athlete.score, "✔" if athlete.is_record else "✖"))    def view_total_scores(self):        """ 查看总分窗口 """        total_window = tk.Toplevel(self.root)        total_window.title("总分")        total_label = tk.Label(total_window, text="所有运动员总分:")        total_label.pack(padx=10, pady=5)        total_score = sum(athlete.score * (2 if athlete.is_record else 1) for athlete in self.scores)        all_scores_label = tk.Label(total_window, text=f"总分: {total_score}")        all_scores_label.pack(padx=10, pady=5)        # 计算平均分、最高分、最低分        if self.scores:            average_score = total_score / len(self.scores)            highest_score = max(athlete.score for athlete in self.scores)            lowest_score = min(athlete.score for athlete in self.scores)        else:            average_score = highest_score = lowest_score = 0        stats_label = tk.Label(total_window, text=f"平均分: {average_score:.2f}, 最高分: {highest_score}, 最低分: {lowest_score}")        stats_label.pack(padx=10, pady=5)        # 各分组的总分        group_scores = {}        for athlete in self.scores:            group = athlete.group            group_score = athlete.score * (2 if athlete.is_record else 1)            group_scores[group] = group_scores.get(group, 0) + group_score                # 显示各组的总分        group_total_label = tk.Label(total_window, text="各分组总分:")        group_total_label.pack(padx=10, pady=5)        for group, group_total in group_scores.items():            group_score_label = tk.Label(total_window, text=f"{group}: {group_total}")            group_score_label.pack(padx=10, pady=5)    def export_to_csv(self):        """ 弹出文件对话框选择保存路径并导出 CSV """        filename = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV files", "*.csv")])        if filename:            with open(filename, mode='w', newline='', encoding='utf-8') as file:                writer = csv.writer(file)                writer.writerow(["分组", "姓名", "名次", "分数", "破纪录"])                for athlete in self.scores:                    writer.writerow([athlete.group, athlete.name, athlete.rank, athlete.score, athlete.is_record])            messagebox.showinfo("成功", f"数据已导出到 {filename}")    def delete_selected(self):        selected_item = self.tree.selection()        if selected_item:            for item in selected_item:                index = self.tree.index(item)                self.tree.delete(item)                # 从列表中删除相应的运动员信息                del self.scores[index]                self.update_displayed_athletes()  # 更新显示        else:            messagebox.showwarning("选择错误", "请先选择一行!")    def open_settings(self):        """ 打开设置分数的窗口 """        settings_window = tk.Toplevel(self.root)        settings_window.title("设置分数")        self.rank_income_vars = {}        for rank in range(1, 9):            tk.Label(settings_window, text=f"第{rank}名分数:").grid(row=rank-1, column=0, padx=5, pady=5)            var = tk.StringVar(value=self.rank_to_score.get(rank, 0))            self.rank_income_vars[rank] = var            tk.Entry(settings_window, textvariable=var).grid(row=rank-1, column=1, padx=5, pady=5)        tk.Button(settings_window, text="确认", command=self.save_settings).grid(row=8, columnspan=2, pady=10)    def save_settings(self):        for rank, var in self.rank_income_vars.items():            try:                score = int(var.get())                self.rank_to_score[rank] = score            except ValueError:                messagebox.showwarning("输入错误", f"名次 {rank} 的分数无效,请输入数字!")                return        for index, athlete in enumerate(self.scores):            # 更新分数            if athlete.rank in self.rank_to_score:                score = self.rank_to_score[athlete.rank]                athlete.score = score  # 更新分数                if index < len(self.tree.get_children()):  # 确保索引有效                    self.tree.item(self.tree.get_children()[index], values=(athlete.group, athlete.name, athlete.rank, score, athlete.is_record))        messagebox.showinfo("成功", "分数设置已更新!")    def toggle_record(self):        selected_item = self.tree.selection()        if selected_item:            item = selected_item[0]            index = self.tree.index(item)            athlete = self.scores[index]  # 获取运动员信息                        athlete.is_record = not athlete.is_record  # 切换破纪录状态            # 更新分数            if athlete.is_record:                athlete.score *= 2            else:                athlete.score //= 2            # 更新树形控件            self.tree.item(item, values=(athlete.group, athlete.name, athlete.rank, athlete.score, "✔" if athlete.is_record else "✖"))    def show_popup(self, event):        try:            selected = self.tree.identify_row(event.y)            if selected:                self.tree.selection_set(selected)                self.popup_menu.post(event.x_root, event.y_root)        except Exception as e:            print(f"Error showing popup menu: {e}")    def open_group_management(self):        """ 打开分组管理窗口 """        group_window = tk.Toplevel(self.root)        group_window.title("管理分组")                tk.Label(group_window, text="自定义分组:").grid(row=0, column=0, padx=10, pady=5)        custom_group_entry = tk.Entry(group_window)        custom_group_entry.grid(row=0, column=1, padx=10, pady=5)        tk.Button(group_window, text="添加分组", command=lambda: self.add_custom_group(custom_group_entry.get())).grid(row=0, column=2, padx=10, pady=5)        tk.Label(group_window, text="当前分组:").grid(row=1, column=0, padx=10, pady=5)        current_groups_var = StringVar(value=", ".join(sorted(self.available_groups)))        tk.Entry(group_window, textvariable=current_groups_var, state='readonly').grid(row=1, column=1, padx=10, pady=5)        tk.Label(group_window, text="删除分组:").grid(row=2, column=0, padx=10, pady=5)        delete_group_entry = tk.Entry(group_window)        delete_group_entry.grid(row=2, column=1, padx=10, pady=5)        tk.Button(group_window, text="删除分组", command=lambda: self.delete_custom_group(delete_group_entry.get())).grid(row=2, column=2, padx=10, pady=5)    def add_custom_group(self, group_name):        """ 添加自定义分组 """        if group_name and group_name not in self.available_groups:            self.available_groups.add(group_name)            self.setup_group_selection()  # 更新分组选择菜单            messagebox.showinfo("成功", f"已添加自定义分组: {group_name}")        else:            messagebox.showwarning("输入错误", "分组名称不能为空或已存在!")    def delete_custom_group(self, group_name):        """ 删除自定义分组 """        if group_name in self.available_groups:            self.available_groups.remove(group_name)            self.setup_group_selection()  # 更新分组选择菜单            messagebox.showinfo("成功", f"已删除分组: {group_name}")        else:            messagebox.showwarning("输入错误", "该分组不存在!")    def show_help(self):        help_message = (            "本软件用于运动会计分管理...\n"            "使用说明:\n"            "1. 请依次输入运动员信息,选择分组或自定义分组。\n"            "2. 点击“添加运动员”来记录。\n"            "3. 点击“查看总分”可以查看所有运动员及各分组的总分。\n"            "4. 右键点击运动员可以切换破纪录状态。\n"            "5. 点击“导出数据”将运动员信息导出为CSV文件。"        )        messagebox.showinfo("帮助", help_message)if __name__ == "__main__":    root = tk.Tk()    app = ScoreApp(root)    root.mainloop()#这个示例代码用了tkinter库来做GUI,其中我采用的的是Tree组件使界面有一个类似于电子表格的管理方式#scv库的作用是可以让统计的数据导出#其中的tkinter库和scv库都是自带的#现在看一下运行后的成果#这里选用如果破纪录是翻倍分数

源码地址:https://download.csdn.net/download/HYP_Coder/90001597?spm=1001.2014.3001.5503

B站视频:嗯?别进来!_哔哩哔哩_bilibili


点击全文阅读


本文链接:http://zhangshiyu.com/post/196889.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1