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

Kivy技术问题:如何移除Label并实现点击赚钱游戏的数值更新

解决Kivy点击更新金币时重复添加Label的问题

嘿,我懂你现在碰到的麻烦了——每次点击都冒出来一个新的数字Label,堆在屏幕上重叠得乱七八糟,对吧?这是因为你每次调用add_widget()都会往屏幕里塞一个全新的Label控件,旧的压根没被移除。最省心高效的解决思路不是去删旧Label,而是只创建一个Label,每次点击只更新它的文本内容,这样既不会有重叠问题,性能也更好。

下面给你两种具体的实现方案:

方案一:在Python代码中初始化并复用Label

这种方式适合习惯在逻辑层处理控件创建的场景:

from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.label import Label

money = 0

class GameScreen(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 初始化时就创建好金币显示Label,存为实例属性
        self.money_label = Label(
            text=str(money),
            color=(1,0,0,1),
            font_size=45,
            size_hint=(0.2,0.1),
            pos_hint={"center_x":0.5, "center_y":0.9}
        )
        self.add_widget(self.money_label)

    def update_money(self):  # 注意:方法名别和全局变量money重名,容易出bug!
        global money
        money += 1
        # 直接更新已有Label的文本,不用新建控件
        self.money_label.text = str(money)
        print(money)

class MyGameApp(App):
    def build(self):
        return GameScreen()

if __name__ == "__main__":
    MyGameApp().run()

对应的kv文件可以简化成这样(补全你没写完的canvas部分):

<GameScreen>:
    name: "GameScreen"
    canvas:
        Color:
            rgba: 1,1,1,1  # 示例背景色,可根据你的需求修改
        Rectangle:
            pos: self.pos
            size: self.size

方案二:在kv文件中定义Label,通过id引用更新

如果你更倾向用kv语言做布局,这种方式更直观:

.py文件:

from kivy.app import App
from kivy.uix.screenmanager import Screen

money = 0

class GameScreen(Screen):
    def update_money(self):
        global money
        money += 1
        # 通过id获取kv里定义好的Label,直接更新文本
        self.ids.money_label.text = str(money)
        print(money)

class MyGameApp(App):
    def build(self):
        return GameScreen()

if __name__ == "__main__":
    MyGameApp().run()

.kv文件:

<GameScreen>:
    name: "GameScreen"
    canvas:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            pos: self.pos
            size: self.size
    Label:
        id: money_label
        text: "0"
        color: (1,0,0,1)
        font_size: 45
        size_hint: 0.2, 0.1
        pos_hint: {"center_x":0.5, "center_y":0.9}

额外提一句:如果非要移除旧Label怎么办?

要是你坚持要每次删除旧控件再添新的,那得先保存旧Label的引用,再调用remove_widget():

class GameScreen(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.current_label = None  # 用这个变量存旧Label的引用

    def money(self):
        global money
        money += 1
        # 先移除旧Label(如果存在的话)
        if self.current_label:
            self.remove_widget(self.current_label)
        # 创建新Label并保存引用
        self.current_label = Label(
            text=str(money),
            color=(1,0,0,1),
            font_size=45,
            size_hint=(0.2,0.1),
            pos_hint={"center_x":0.5, "center_y":0.9}
        )
        self.add_widget(self.current_label)
        print(money)

不过这种方法不如复用Label高效,频繁创建销毁控件会影响性能,所以还是优先推荐前面两种复用方案。

内容的提问来源于stack exchange,提问作者Adam Kamil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:51:17