You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter游戏Score标签无法更新:实现积分收集时实时刷新原有标签

问题解决:Tkinter游戏分数标签不更新,重复生成新标签

问题原因

  1. 变量作用域错误:初始创建的score_value标签是login函数内的局部变量,addScore函数无法访问到这个对象,只能重新创建新标签。
  2. 更新方式错误:每次收集积分时,addScore里都新建tk.Label并执行pack(),导致界面不断新增分数标签,而非更新原有标签的内容。

修复方案

关键修改点

  1. 将score_value声明为全局变量,让addScore能访问到最初创建的标签对象。
  2. 用score_value.config(text=新分数)替代新建标签的代码,直接更新原有标签的文本。
  3. 内存中维护当前分数,减少重复查询数据库的操作,提升运行效率。

修改后的完整代码

import tkinter as tk
import sqlite3
import random

conn = sqlite3.connect("Benutzer.db")
c = conn.cursor()

c.execute("CREATE TABLE IF NOT EXISTS Benutzer (username TEXT, password TEXT, PRIMARY KEY (username))")

conn2 = sqlite3.connect("Punkte.db")
c2 = conn2.cursor()

c2.execute("CREATE TABLE IF NOT EXISTS Punkte (username TEXT, score INTEGER, PRIMARY KEY (username))")

conn.commit()
conn2.commit()

points = 0
score_value = 0  # 全局变量初始化

def register():
    user = username.get()
    pwd = password.get()

    c.execute("SELECT username FROM Benutzer WHERE username = ?", [user])
    result = c.fetchone()

    if result:
        error_label = tk.Label(login_window, text="Dieser Benutzer existiert bereits.", fg="red")
        error_label.pack()

    else:
        c.execute("INSERT INTO Benutzer VALUES ('" + user + "', '" + pwd + "')")
        c2.execute("INSERT INTO Punkte VALUES ('" + user + "', 0)")
        conn.commit()
        conn2.commit()
        create_label = tk.Label(login_window, text="Du hast dich erfolgreich registriert.", fg="green")
        create_label.pack()

def login():
    global score_value  # 声明使用全局变量
    user = username.get()
    pwd = password.get()

    c.execute("SELECT * FROM Benutzer WHERE username = ? AND password = ?", (user, pwd))
    result = c.fetchone()

    if result:
        login_window.destroy()

        score_window = tk.Tk()
        score_window.title("Punktestand")
        score_window.geometry("350x325")

        user_label = tk.Label(score_window, text=f"Willkommen, {user}!")
        user_label.pack()

        score_label = tk.Label(score_window, text="Ihr Punktestand ist:")
        score_label.pack()

        c2.execute("SELECT score FROM Punkte WHERE username = ?", [user])
        score = c2.fetchone()

        if score:
            score_value = tk.Label(score_window, text=score[0])
            score_value.pack()
            current_score = score[0]  # 内存中维护当前分数,避免重复查库
        else:
            error_message = tk.Label(score_window, text="Kein Punktestand gefunden.")
            error_message.pack()
            current_score = 0

        canvas = tk.Canvas(score_window, width=300, height=200, bg="white")
        canvas.pack()

        circle = canvas.create_oval(150, 100, 170, 120, fill="blue")
        point = canvas.create_oval(0, 0, 10, 10, fill="red")

        def placePoint():
            x = random.randint(0, 290)
            y = random.randint(0, 190)
            canvas.coords(point, x, y, x+10, y+10)

        placePoint()

        def moveLeft(event):
            x1, y1, x2, y2 = canvas.coords(circle)
            if x1 > 0:
                canvas.move(circle, -10, 0)

        def moveRight(event):
            x1, y1, x2, y2 = canvas.coords(circle)
            if x2 < 300:
                canvas.move(circle, 10, 0)

        def moveUp(event):
            x1, y1, x2, y2 = canvas.coords(circle)
            if y1 > 0:
                canvas.move(circle, 0, -10)

        def moveDown(event):
            x1, y1, x2, y2 = canvas.coords(circle)
            if y2 < 200:
                canvas.move(circle, 0, 10)

        canvas.bind("<Left>", moveLeft)
        canvas.bind("<Right>", moveRight)
        canvas.bind("<Up>", moveUp)
        canvas.bind("<Down>", moveDown)

        canvas.focus_set()

        def checkCollision():
            x1, y1, x2, y2 = canvas.coords(circle)
            x3, y3, x4, y4 = canvas.coords(point)
            cx = (x1 + x2) / 2
            cy = (y1 + y2) / 2
            px = (x3 + x4) / 2
            py = (y3 + y4) / 2
            distance = ((cx - px) ** 2 + (cy - py) ** 2) ** 0.5

            return distance < 10

        def update():
            if checkCollision():
                placePoint()
                addScore()
            score_window.after(100, update)

        update()

        def addScore():
            nonlocal current_score  # 访问login函数内的current_score变量
            current_score += 1
            # 更新数据库
            c2.execute("UPDATE Punkte SET score = ? WHERE username = ?", [current_score, user])
            conn2.commit()
            # 更新原有标签的文本
            score_value.config(text=current_score)

        close_button = tk.Button(score_window, text="Schließen", command=score_window.destroy)
        close_button.pack()

        score_window.mainloop()

    else:
        error_label = tk.Label(login_window, text="Falscher Benutzername oder Passwort.", fg="red")
        error_label.pack()

login_window = tk.Tk()
login_window.title("Anmeldung")
login_window.geometry("325x175")

instruction_label = tk.Label(login_window, text="Bitte geben Sie Ihren Benutzernamen und Ihr Passwort ein.")
instruction_label.pack()

username = tk.StringVar()
password = tk.StringVar()

username_label = tk.Label(login_window, text="Benutzername:")
username_label.pack()
password_label = tk.Label(login_window, text="Passwort:")
password_label.pack()

username_entry = tk.Entry(login_window, textvariable=username)
username_entry.pack()
password_entry = tk.Entry(login_window, textvariable=password, show="*")
password_entry.pack()

login_button = tk.Button(login_window, text="Anmelden", command=login)
login_button.pack()
register_button = tk.Button(login_window, text="Registrieren", command=register)
register_button.pack()

login_window.mainloop()

额外说明

  • 新增current_score变量在内存中维护分数,避免每次碰撞都查询数据库,提升性能。
  • 简化checkCollision函数的返回逻辑,直接返回布尔值。
  • 移除无意义的变量重复声明(如circle, point这类无实际作用的代码)。

内容的提问来源于stack exchange,提问作者Kevin Pagel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 16:34:54