吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1585|回复: 14
收起左侧

[其他原创] 闲来无聊写个简易的html娱乐用的计分器

[复制链接]
bloodfog 发表于 2024-6-18 20:42
本帖最后由 bloodfog 于 2024-6-19 15:27 编辑

闲来无聊写个简易的html娱乐用的计分器
[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>QP计分器</title>
    <style>
        body {
            font-family: "仿宋";
            background-color: #f0f0f0;
            margin: 0;
            padding: 20px;
            font-size: 12px;
        }
        .container {
            max-width: 98%;
            margin: 0 auto;
            background-color: #fff;
            padding: 5px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            overflow-x: auto; /* 添加水平滚动条 */
        }
        .controls {
            text-align: center;
            margin-bottom: 5px;
            font-size:12px;
        }
        .controls input, .controls button {
            padding: 5px;
            margin: 5px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            height: 32px;
            line-height: 22px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            table-layout: fixed; /* 表格宽度固定 */
        }
        th, td {
            border: 1px solid #ddd;
            padding: 5px;
            text-align: center;
            white-space: nowrap;
        }
        th {
            background-color: #f4f4f4;
        }
        .delete-btn {
            color: red;
            cursor: pointer;
        }
        input[type=number] {
            width: 100%;
            border: none;
            text-align: center;
            box-sizing: border-box;
        }
        input[type=number]:focus {
            border: 1px solid #ccc; /* 输入状态时的边框颜色为淡灰色 */
            outline: none;
        }
        tbody tr:nth-child(odd) {
            background-color: #d8eafc; /* 奇数行背景淡蓝色 */
        }
        tbody tr:nth-child(even) {
            background-color: #d0f0c0; /* 偶数行背景淡绿色 */
        }
        tbody tr:nth-child(odd) input[type=number] {
            background-color: #d8eafc; /* 奇数行背景淡蓝色 */
            border: 1px solid #d8eafc;
        }
        tbody tr:nth-child(even) input[type=number] {
            background-color: #d0f0c0; /* 偶数行背景淡绿色 */
            border: 1px solid #d0f0c0;
        }
        .alert-box {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: #fff;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            z-index: 1000;
            border-radius: 10px;
            text-align: center;
        }
        .alert-box h2 {
            margin: 0 0 10px 0;
        }
        .alert-box p {
            margin: 0 0 20px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="controls">
            <input type="text" id="username" placeholder="输入玩家昵称" style="height:20px; width:90px; line-height:20px; padding:5px; font-size:14px;" autocomplete="off">
            <button>新玩家</button>
            <button>添加一局</button>
            <button>重置</button>
        </div>
        <table id="scoreTable">
            <thead>
                <tr>
                    <th style="width:70px; height:25px; line-height:25px;">玩家</th>
                    <th style="width:60px;">合计</th>
                    <th style="width:60px;">操作</th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>

    <script>
        let users = JSON.parse(localStorage.getItem('users')) || [];
        let rounds = parseInt(localStorage.getItem('rounds')) || 0;

        function saveData() {
            localStorage.setItem('users', JSON.stringify(users));
            localStorage.setItem('rounds', rounds.toString());
        }

        function loadData() {
            if (users.length > 0) {
                for (let i = 0; i < rounds; i++) {
                    addRoundHeader(i);
                }
                users.forEach(user => addUserToTable(user.username, user.scores));
            }
        }

        function addUser() {
            const username = document.getElementById('username').value;
            if (!username) {
                showAlert("请先输入玩家昵称");
                return;
            }
            if (username && !users.find(user => user.username === username)) {
                const user = { username: username, scores: Array(rounds).fill(0) };
                users.push(user);
                addUserToTable(username, user.scores);
                saveData();
                document.getElementById('username').value = '';
            }
        }

        function addUserToTable(username, scores = []) {
            const table = document.getElementById('scoreTable').getElementsByTagName('tbody')[0];
            const row = table.insertRow();
            row.setAttribute('data-username', username);

            const cell1 = row.insertCell(0);
            cell1.textContent = username;

            const totalCell = row.insertCell(1);
            totalCell.textContent = scores.reduce((a, b) => a + b, 0);

            scores.forEach(score => {
                const scoreCell = row.insertCell(-1);
                scoreCell.innerHTML = `<input type="number" value="${score}">`;
            });

            const cell2 = row.insertCell(-1);
            cell2.innerHTML = '<span class="delete-btn">移除</span>';
        }

        function confirmDeleteUser(element) {
            showConfirm("确定要移除此玩家吗?", () => {
                const row = element.parentNode.parentNode;
                const username = row.getAttribute('data-username');
                users = users.filter(user => user.username !== username);
                row.remove();
                saveData();
            });
        }

        function addRound() {
            rounds++;
            users.forEach(user => user.scores.unshift(0));
            addRoundHeader(rounds - 1);
            saveData();
        }

        function addRoundHeader(roundIndex) {
            const table = document.getElementById('scoreTable');
            const th = document.createElement('th');
            th.textContent = '第 ' + (roundIndex + 1) + ' 局';
            th.style.width = '60px'; // 固定宽度为60px
            const headerRow = table.getElementsByTagName('thead')[0].rows[0];
            headerRow.insertBefore(th, headerRow.cells[2]);

            const tbody = table.getElementsByTagName('tbody')[0];
            Array.from(tbody.rows).forEach((row) => {
                const cell = row.insertCell(2);
                cell.innerHTML = `<input type="number" value="0">`;
            });
        }

        function updateScore(element) {
            const row = element.parentNode.parentNode;
            const username = row.getAttribute('data-username');
            const user = users.find(user => user.username === username);
            const index = Array.from(row.cells).indexOf(element.parentNode) - 2;
            user.scores[index] = Number(element.value);
            row.cells[1].textContent = user.scores.reduce((a, b) => a + b, 0);
            saveData();
        }

        function resetData() {
            showConfirm("确定要重置全部数据吗?", () => {
                users = [];
                rounds = 0;
                saveData();
                document.getElementById('scoreTable').getElementsByTagName('tbody')[0].innerHTML = '';
                document.getElementById('scoreTable').getElementsByTagName('thead')[0].innerHTML = '<tr><th style="width:70px;">玩家</th><th style="width:60px;">合计</th><th style="width:60px;">操作</th></tr>';
            });
        }

        function showAlert(message) {
            const alertDiv = document.createElement('div');
            alertDiv.className = 'alert-box';
            alertDiv.innerHTML = `
                <h2>温馨提示</h2>
                <p>${message}</p>
                <button>明白了</button>
            `;
            document.body.appendChild(alertDiv);
        }

        function showConfirm(message, onConfirm) {
            const confirmDiv = document.createElement('div');
            confirmDiv.className = 'alert-box';
            confirmDiv.innerHTML = `
                <h2>温馨提示</h2>
                <p>${message}</p>
                <button id="confirm-yes">确定</button>
                <button>取消</button>
            `;
            document.body.appendChild(confirmDiv);
            document.getElementById('confirm-yes').addEventListener('click', function () {
                onConfirm();
                confirmDiv.remove();
            });
        }

        document.addEventListener('DOMContentLoaded', loadData);
    </script>
</body>
</html>


python版本
[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import json
import os
import sys
from PIL import Image, ImageTk

def resource_path(relative_path):
    """ 获取资源文件的绝对路径 """
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)

class ScoreKeeper:
    def __init__(self, root):
        self.root = root
        self.root.title("计分器")
        self.root.geometry("800x400")

        # 更换程序图标
        icon_path = resource_path('head.ico')
        print(f"Icon path: {icon_path}")  # 打印图标路径
        try:
            self.root.iconbitmap(icon_path)  # 设置窗口图标
        except Exception as e:
            print(f"Error setting icon: {e}")
        
        # 使用PIL加载图标并设置
        try:
            icon = Image.open(icon_path)
            icon = ImageTk.PhotoImage(icon)
            self.root.iconphoto(False, icon)
        except FileNotFoundError:
            print("Icon file not found. Please ensure 'head.ico' is in the correct directory.")

        self.users = []
        self.rounds = 0

        self.load_data()

        self.controls_frame = tk.Frame(root, padx=5, pady=5)
        self.controls_frame.pack(fill=tk.X)

        self.username_entry = tk.Entry(self.controls_frame, font=("仿宋", 14))
        self.username_entry.grid(row=0, column=0, padx=5, pady=5)
        self.username_entry.config(width=10)

        self.add_user_btn = tk.Button(self.controls_frame, text="新玩家", command=self.add_user, font=("仿宋", 12))
        self.add_user_btn.grid(row=0, column=1, padx=5, pady=5)

        self.add_round_btn = tk.Button(self.controls_frame, text="添加一局", command=self.add_round, font=("仿宋", 12))
        self.add_round_btn.grid(row=0, column=2, padx=5, pady=5)

        self.reset_btn = tk.Button(self.controls_frame, text="重置", command=self.reset_data, font=("仿宋", 12))
        self.reset_btn.grid(row=0, column=3, padx=5, pady=5)

        self.table_frame = tk.Frame(root, padx=5, pady=5)
        self.table_frame.pack(fill=tk.BOTH, expand=True)

        self.scrollbar_x = ttk.Scrollbar(self.table_frame, orient="horizontal")
        self.scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.scrollbar_y = ttk.Scrollbar(self.table_frame, orient="vertical")
        self.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)

        self.table = ttk.Treeview(self.table_frame, columns=[], show="headings", selectmode="browse",
                                  xscrollcommand=self.scrollbar_x.set, yscrollcommand=self.scrollbar_y.set)
        self.scrollbar_x.config(command=self.table.xview)
        self.scrollbar_y.config(command=self.table.yview)

        self.table.pack(fill=tk.BOTH, expand=True)
        self.table.bind("<Button-1>", self.handle_click)

        self.render_table()

    def save_data(self):
        data = {"users": self.users, "rounds": self.rounds}
        with open("data.json", "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=4)

    def load_data(self):
        try:
            with open("data.json", "r", encoding="utf-8") as f:
                data = json.load(f)
                self.users = data.get("users", [])
                self.rounds = data.get("rounds", 0)
        except FileNotFoundError:
            self.users = []
            self.rounds = 0

    def add_user(self):
        username = self.username_entry.get()
        if not username:
            messagebox.showinfo("温馨提示", "请先输入玩家昵称")
            return
        if username and not any(user['username'] == username for user in self.users):
            user = {"username": username, "scores": [0] * self.rounds}
            self.users.append(user)
            self.render_table()
            self.save_data()
            self.username_entry.delete(0, tk.END)

    def add_round(self):
        self.rounds += 1
        for user in self.users:
            user['scores'].append(0)
        self.render_table()
        self.save_data()

    def update_score(self, user_index, round_index, score):
        self.users[user_index]['scores'][round_index] = score
        self.render_table()
        self.save_data()

    def delete_user(self, user_index):
        confirm = messagebox.askyesno("温馨提示", "确定要移除此玩家吗?")
        if confirm:
            del self.users[user_index]
            self.render_table()
            self.save_data()

    def reset_data(self):
        confirm = messagebox.askyesno("温馨提示", "确定要重置全部数据吗?")
        if confirm:
            self.users = []
            self.rounds = 0
            self.save_data()
            self.render_table()

    def render_table(self):
        for i in self.table.get_children():
            self.table.delete(i)

        columns = ["username", "total"] + [f"round_{i+1}" for i in range(self.rounds)][::-1] + ["actions"]
        self.table["columns"] = columns
        self.table.heading("username", text="玩家")
        self.table.heading("total", text="合计")
        for i in range(self.rounds):
            self.table.heading(f"round_{i+1}", text=f"第{i+1}局")
        self.table.heading("actions", text="操作")
        
        self.table.column("username", width=80, anchor=tk.CENTER, minwidth=80)
        self.table.column("total", width=80, anchor=tk.CENTER, minwidth=80)
        for i in range(self.rounds):
            self.table.column(f"round_{i+1}", width=80, anchor=tk.CENTER, minwidth=80)
        self.table.column("actions", width=80, anchor=tk.CENTER, minwidth=80)

        for user_index, user in enumerate(self.users):
            total_score = sum(user['scores'])
            values = [user['username'], total_score] + user['scores'][::-1] + ["移除"]
            tag = 'evenrow' if user_index % 2 == 0 else 'oddrow'
            self.table.insert("", "end", values=values, tags=(tag,))

        # 添加样式使内容居中对齐
        style = ttk.Style()
        style.configure("Treeview.Heading", anchor="center")
        style.configure("Treeview", rowheight=25)
        style.configure("Treeview", highlightthickness=1, bd=1, relief="solid")

        # 添加表格边框线
        style.map("Treeview", background=[("selected", "#0099FF")], foreground=[("selected", "white")])
        style.configure("Treeview", highlightthickness=1, bd=1, relief="solid")
        style.layout("Treeview", [('Treeview.treearea', {'sticky': 'nswe'})])

        # 添加列之间的边框线
        style.configure("Treeview", bordercolor="black", borderwidth=1, relief="solid")

        # 添加行之间的背景颜色交替
        self.table.tag_configure('oddrow', background='white')
        self.table.tag_configure('evenrow', background='lightgrey')

        # 确保滚动条在添加新列后仍然有效
        self.table.update_idletasks()

    def handle_click(self, event):
        region = self.table.identify_region(event.x, event.y)
        if region == "cell":
            row_id = self.table.identify_row(event.y)
            column = self.table.identify_column(event.x)
            col_num = int(column.replace("#", "")) - 1
            if col_num == len(self.users[0]["scores"]) + 2:  # 操作列
                user_index = self.table.index(row_id)
                self.delete_user(user_index)
            elif 2 <= col_num <= len(self.users[0]["scores"]) + 1:  # 分数列
                user_index = self.table.index(row_id)
                round_index = len(self.users[0]["scores"]) - (col_num - 2) - 1  # 修正索引计算
                new_score_str = simpledialog.askstring("更新分数", f"请输入 {self.users[user_index]['username']} 的第 {round_index + 1} 局分数:")
                if new_score_str is not None:
                    try:
                        new_score = int(new_score_str)
                        self.update_score(user_index, round_index, new_score)
                    except ValueError:
                        messagebox.showerror("输入错误", "请输入有效的整数分数")

if __name__ == "__main__":
    root = tk.Tk()
    app = ScoreKeeper(root)
    root.mainloop()


python版本

python版本

计分器

计分器

score.zip

2.6 KB, 下载次数: 17, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 5吾爱币 +11 热心值 +3 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
随遇而安8 + 1 + 1 用心讨论,共获提升!
fofawb + 1 谢谢@Thanks!
chenpi0903 + 1 我很赞同!
小众资源 + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

随遇而安8 发表于 2024-6-18 21:33
复制到文本文档里,改后缀.html,点击button没反应呢?
n3iuarem3t 发表于 2024-6-19 11:34
希望更新一下,添加分类和自动计分,比如斗地主,只需要给地主修改分数,其他两家就可以自动计算分数,目前这个需要一个个填,还是比较麻烦的,另外整体可以让字体大一点
ZhjhJZ 发表于 2024-6-18 22:03
 楼主| bloodfog 发表于 2024-6-18 22:13
随遇而安8 发表于 2024-6-18 21:33
复制到文本文档里,改后缀.html,点击button没反应呢?

直接下载 附件吧,代码附件打包了
chplifeng 发表于 2024-6-19 01:25
支持一下
meder 发表于 2024-6-19 02:05
感谢分享
vzzwcom 发表于 2024-6-19 08:36

感谢分享
shishiaiyin 发表于 2024-6-19 08:55
谢谢分享
静静想我1970 发表于 2024-6-19 09:17
原来积分是这么水出来的,果然我还是太咸鱼
Yukeer666 发表于 2024-6-19 09:29
感谢分享,很有帮助
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 13:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表