Kivy GridLayout, обращающийся к строкам и столбцам, возвращает None.

У меня есть следующий код:

class MyGridLayout(GridLayout):
    def __init__(self, **kwargs):
        super(MyGridLayout, self).__init__(**kwargs)

class Board(Widget):

    my_layout = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Board, self).__init__(**kwargs)

    def on_my_layout(self, instance, value):
        print self.my_layout.cols

class MyApp(App):

    def build(self):
        return Board()

if __name__ == '__main__':
    MyApp().run()

А это мой kv-файл:

<Board>:
    my_layout: my_layout
    MyGridLayout:
        id: my_layout
        cols: 10
        rows: 10

В методе on_my_layout я хочу напечатать, сколько столбцов имеет мой экземпляр MyGridLayout. Но он всегда возвращает мне None. Если я хочу получить доступ к строкам, он также возвращает None. Что мне нужно изменить в моем коде Python или на моем языке kivy, чтобы получить доступ к правильным значениям строк и столбцов MyGridLayout? Он должен вернуть rows = 10 и cols = 10.


person Caaarlos    schedule 06.05.2016    source источник


Ответы (1)


<Board>:
    my_layout: my_layt ## This
    MyGridLayout:
        id: my_layt
        cols: 10
        rows: 10

Это не работает, потому что вы назначаете несуществующий виджет ObjectProperty, следовательно, YourObjectProperty.cols==None. В основном вам нужно сделать это:

<Board>:
    MyGridLayout:
        id: my_layt
        cols: 10
        rows: 10
    my_layout: my_layt ## This

что вызовет ошибку в kv. Однако, если вы сделаете это в __init__(), так что ваш виджет уже есть и работает, он напечатает его без проблем. Не используйте одни и те же имена для идентификатора и переменной, иначе это может вообще не работать.

class Board(Widget):

    my_layout = ObjectProperty(None)
    def __init__(self, **kwargs):
        super(Board, self).__init__(**kwargs)
        self.my_layout = self.ids.my_layt
person Peter Badida    schedule 06.05.2016
comment
Спасибо, это решило мою проблему. Можете ли вы сказать мне, почему метод on_my_layout вызывается первым, чем __init__? - person Caaarlos; 06.05.2016
comment
@Caaarlos не метод, назначение идет первым. Метод вызывается, когда вы меняете my_layout, который находится в .py, на ObjectProperty, поэтому, когда вы назначаете что-то этому в .kv, он запускает ваш on_my_layout и что-то печатает. Вот почему вам нужно дождаться инициализации виджета, а затем назначить инициализированный (настоящий) виджет переменной, которая будет вызывать вашу функцию. Первый код в моем ответе: виджета нет, когда my_layout: my_layt. - person Peter Badida; 06.05.2016
comment
Спасибо, теперь я знаю, что происходит в моем коде! - person Caaarlos; 06.05.2016