Tkinter游戏Score标签无法更新:实现积分收集时实时刷新原有标签
问题解决:Tkinter游戏分数标签不更新,重复生成新标签
问题原因
- 变量作用域错误:初始创建的
score_value标签是login函数内的局部变量,addScore函数无法访问到这个对象,只能重新创建新标签。 - 更新方式错误:每次收集积分时,
addScore里都新建tk.Label并执行pack(),导致界面不断新增分数标签,而非更新原有标签的内容。
修复方案
关键修改点
- 将
score_value声明为全局变量,让addScore能访问到最初创建的标签对象。 - 用
score_value.config(text=新分数)替代新建标签的代码,直接更新原有标签的文本。 - 内存中维护当前分数,减少重复查询数据库的操作,提升运行效率。
修改后的完整代码
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
相关产品推荐
相关产品推荐

