【问题标题】:How to prevent properties from being shared between widgets?如何防止属性在小部件之间共享?
【发布时间】:2016-04-27 20:58:23
【问题描述】:

我正在开发一款使用 Kivy 的游戏,玩家可以通过按键来发射炸弹。这是一个简化的函数:

def shoot(self, world):
    # self is the player widget
    bomb = Bomb(pos=self.pos)
    world.add_entity(bomb)

有趣的是,当玩家射击时,无论他走到哪里,炸弹都会跟着他移动。

调试后我意识到这是因为播放器和炸弹共享velocity 属性。

Player 类和Bomb 类都继承了Entity,它在类级别定义了velocity = ObjectProperty(Vector(0, 0))。运行时调试显示这两个对象引用了完全相同的对象。

问题是,Kivy 属性实际上应该在每个实例上创建单独的属性。那么为什么会出现这种不需要的共享状态,我该如何解决呢?

解决方案

感谢@Tshirtman 对this question 答案的评论,我找到了问题和解决方案。

事实证明 Kivy 属性有一个陷阱,实例化它们时设置的初始值将由类的所有实例共享。

澄清一下:

# this implementation results in the property shared by all instances

class MyWidget(Widget):
    my_field = ObjectProperty(MyObject())

w1 = MyWidget()
w2 = MyWidget()
w1.my_field is w2.my_field  # True

如您所见,my_field 实际上是在两个实例之间共享的。

为避免这种行为,除了设置类级属性外,请确保在特定对象上设置属性。

例如:

class MyWidget(Widget):
    my_field = ObjectProperty()

    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        self.my_field = MyObject()  # explicitly set the value on the object

w1 = MyWidget()
w2 = MyWidget()
w1.my_field is w2.my_field  # False    

当显式设置字段的值时,该字段不会在实例之间共享。希望这对某人有所帮助。

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    Kivy 的小部件不会自动执行此操作,可能是您编写了无意中导致它的代码。如果您需要帮助追踪问题,请发布一个可运行的示例来演示该问题。

    【讨论】:

    • 调试显示问题在于播放器和炸弹都引用了相同的velocity 对象,该对象是使用ObjectProperty(Vector(0, 0)) 创建的。问题是,玩家和炸弹都应该有自己的velocity 矢量对象,但事实并非如此。你能帮我理解这个问题吗?
    猜你喜欢
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2010-11-29
    • 1970-01-01
    • 2011-08-20
    • 2020-04-07
    • 1970-01-01
    相关资源
    最近更新 更多