Kivy 绑定到 on_property 似乎不起作用

Kivy binding to on_property doesn't seem to work

本质上,我有一个带正方形的网格,我跟踪哪些正方形被占用,每个正方形上都有一个 BooleanProperty。这是我代码中所有地方的简化版本我声明 "occupied" 属性:

class Board(GridLayout):
    def __init__(self):
        super().__init__()
        self.cols = 4
        self.grid = []
        self.create_slots()




    def create_slots(self):
        for i in range(10):
            self.grid.append([])
            for j in range(4):
                temp = Square(i,j, "sideboard")
                self.grid[i].append(temp)
                self.add_widget(temp)
                temp.bind(on_occupied = self.do_a_thing)


    def do_a_thing(self):
        for square in self.children:
            #do a thing

class Square(Button):
    def __init__(self, row, col, type):
        self.row = row
        self.col = col
        self.id = str(self.row) + "," + str(self.col)
        self.type = type
        self.occupied = BooleanProperty(False)
        super().__init__()

我的目标是绑定 "do_a_thing" 方法,每次 "occupied" 属性 的值发生变化时调用该方法。因为 Square class 在我的应用程序的其他地方使用,所以我不想在 kivy 语言中设置 on_occupied 的回调,我希望避免创建 Square sub-class 只是为了改变一个绑定。

当我 运行 我的代码时,它没有抛出任何错误,而且我已经验证 "occupied" 属性 确实发生了变化。但是 "do_a_thing" 方法永远不会被触发。谁能告诉我我做错了什么?

请注意,对于 属性 my_property,更改事件也称为 my_property。回调接收两个参数:instance that fired the event, and new value of the property, as shown in the docs。另外,如果 class 有一个名为 on_propertyname 的方法,它也会被调用。 这是一个适合我的独立示例:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.properties import BooleanProperty

class Board(GridLayout):
    def __init__(self, **kwargs):
        super(Board, self).__init__(**kwargs)
        for i in range(10):
            self.add_widget(Square())
        for square in self.children:
            print square
            square.bind(occupied=self.do_a_thing)

    def do_a_thing(self, *args):
        print "hello from {}, new state: {}".format(*args)
        for square in self.children:
            pass
            #do a thing

class Square(Button):
     occupied = BooleanProperty(False)
     def on_occupied(self, *args):
         print "Callback defined in class: from {} state {}".format(*args)


class mApp(App):
    def build(self):
        return Builder.load_string("""
Board:
    cols: 4
    rows: 3
<Square>:
    on_press: self.occupied = ~self.occupied
""")
mApp().run()