Kivy Builder — динамическая кнопка on_press

Я создавал приложение, используя kivy. В моем приложении у меня есть кнопка, которая читает из каталога и добавляет кнопку для каждого файла в каталоге во всплывающий виджет.

Код для создания кнопок работает хорошо, и никаких проблем. Моя проблема заключается в том, что я назначаю on_press или другое событие для запуска метода внутри моего main.py.

фрагмент main.py;

    class Container(BoxLayout):
        container=ObjectProperty(None)
        SelectGamePopup = Popup(title='Start A New Game', size_hint=(None, None))
        ...
        def newGame(self):
            BlankLayout = BoxLayout(orientation='vertical')
            BlankGrid = GridLayout(cols=3, size_hint_y=7)
            DismissButton = Button(text='Back', size_hint_y=1)
            DismissButton.bind(on_press=Container.SelectGamePopup.dismiss)

            for files in os.listdir(os.path.join(os.getcwd(), 'Games')):
                addFile = files.rstrip('.ini')
                BlankGrid.add_widget(Builder.load_string('''
Button:
text:''' + "\"" + addFile + "\"" + '''
on_press: root.gameChooser(''' + "\"" + addFile + "\"" + ''')
'''))

            BlankLayout.add_widget(BlankGrid)
            BlankLayout.add_widget(DismissButton)

            Container.SelectGamePopup.content = BlankLayout
            Container.SelectGamePopup.size=(self.container.width - 10, self.container.height - 10)
            Container.SelectGamePopup.open()

        def gameChooser(self, game):
            Container.SelectGamePopup.dismiss
            print(game)

Проблема заключается в on_press: root.gameChooser(''' + "\"" + addFile + "\"" + '''). Ошибка возвращена; AttributeError: 'Button:' object has no attribute 'gameChooser'.

Как заставить эту динамически созданную кнопку вызывать нужную мне функцию, а также передать динамическое имя этой функции?

Большое спасибо!


person Chazara    schedule 30.04.2015    source источник


Ответы (1)


создайте кнопку на языке python и свяжите с on_press и отправьте аргумент, используя частичное

from functools import partial 
class Container(BoxLayout):
    container=ObjectProperty(None)
    SelectGamePopup = Popup(title='Start A New Game', size_hint=(None, None))
    ...
    def newGame(self):
        BlankLayout = BoxLayout(orientation='vertical')
        BlankGrid = GridLayout(cols=3, size_hint_y=7)
        DismissButton = Button(text='Back', size_hint_y=1)
        DismissButton.bind(on_press=Container.SelectGamePopup.dismiss)

        for files in os.listdir(os.path.join(os.getcwd(), 'Games')):
            addFile = files.rstrip('.ini')
            # normal button
            MydynamicButton = Button(text=addFile)
            # bind and send 
            MydinamicButton.bind(on_press = partial(self.gamechooser ,addFile)) #use partila to send argument to callback
            BlankGrid.add_widget(MydinamicButton)


        BlankLayout.add_widget(BlankGrid)
        BlankLayout.add_widget(DismissButton)

        Container.SelectGamePopup.content = BlankLayout
        Container.SelectGamePopup.size=(self.container.width - 10, self.container.height - 10)
        Container.SelectGamePopup.open()
    # you can use *args to get all extra argument that comes with on_press in a list
    def gameChooser(self, game ,*args):
        Container.SelectGamePopup.dismiss
        print(game)
person rawinput    schedule 30.04.2015