pythonpython-3.xbeeware

Toga/Beeware button not working as it should, code returning output without button press


I just started working with Toga and Beeware (been following their tutorials) to make a windows app. I have a function that goes through an excel file and returns a list of values. The user pushes buttons to decide the timeframe in which the functions works. But, when I start the app, I already have a result in the text box without ever pressing the button. And the result doesn't change even when different buttons are pressed. This is the code:

    import toga
    from toga.style import Pack
    from toga.style.pack import COLUMN, ROW, LEFT, RIGHT, Pack


class MyFunction(toga.App):

    def startup(self):
        main_box = toga.Box()
        top_box = toga.Box()
        bot_box = toga.Box()
        result = toga.Box()

        result_A = toga.TextInput(readonly=True)
        result_L = toga.Label('This is your output: ', style=Pack(text_align=RIGHT))

        def find_it(int):
            '''does stuff'''
            result_A.value = output


        button0 = toga.Button('hr1', on_press=find_it(1), style=Pack(padding=5))
        button1 = toga.Button('hr2', on_press=find_it(2), style=Pack(padding=5))
        button2 = toga.Button('hr3', on_press=find_it(3), style=Pack(padding=5))
        button3 = toga.Button('hr4', on_press=find_it(4), style=Pack(padding=5))
        button4 = toga.Button('hr5', on_press=find_it(5), style=Pack(padding=5))
        button5 = toga.Button('hr6', on_press=find_it(6), style=Pack(padding=5))
        button6 = toga.Button('hr7', on_press=find_it(7), style=Pack(padding=5))
        button7 = toga.Button('hr8', on_press=find_it(8), style=Pack(padding=5))
        button8 = toga.Button('hr9', on_press=find_it(9), style=Pack(padding=5))
        button9 = toga.Button('hr10', on_press=find_it(10), style=Pack(padding=5))


        top_box.add(button0)
        top_box.add(button1)
        top_box.add(button2)
        top_box.add(button3)
        top_box.add(button4)
        bot_box.add(button5)
        bot_box.add(button6)
        bot_box.add(button7)
        bot_box.add(button8)
        bot_box.add(button9)

        result.add(result_L)
        result.add(result_A)

        main_box.add(top_box)
        main_box.add(bot_box)
        main_box.add(result)

        main_box.style.update(direction=COLUMN, padding_top=10)
        top_box.style.update(direction=ROW, padding=5)
        bot_box.style.update(direction=ROW, padding=5)
        result.style.update(direction=ROW, padding=10)

        self.main_window = toga.MainWindow(title=self.formal_name)
        self.main_window.content = main_box
        self.main_window.show()


def main():
    return MyFunction()

I think the problem is in the "on_press=find_it()" part, because the output is always related to the last button defined (so button9, meaning find_it will always use 10 as an argument). I've tried changing the arguments in the find_it function, adding "self, widget, int" in different order; I've also tried addine "self." on the "on_press=" argument, to no success. I'm new to Toga and all but also but the documentation is very limited and I can't pinpoint exactly what I'm doing wrong. I'd be glad if someone could point me to some extensive documentation so I can learn by myself as well. Or even point me to a different GUI framework compatible with Beeware but with more documentation and/or ease of use (even though Toga looks pretty intuitive). Thank you.


Solution

  • on_press=find_it(1) calls find_it immediately, and then passes its return value (None) as the on_press handler.

    Instead, you should define find_it like this:

    def find_it(n):
       def on_press(button):
            '''does stuff with n'''
            result_A.value = output       
       return on_press