omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Button action in a class

    Pythonista
    3
    7
    2703
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • donnieh
      donnieh last edited by

      I have a ui.button created in a class function. The button action is pointing to a different function in the same class.

      The action will not call when the button is pushed. Should this work? ( This is simplified logic of the actual code)

      class Note:
      
          def f1(self):
               print 'hello'
      
          def f2(self):
               b = ui.button()
               b. action = f1
      
      c = Note()
      c.f2()
      
      1 Reply Last reply Reply Quote 0
      • dgelessus
        dgelessus last edited by

        In the line b.action = f1 you're trying to set the global f1 as the action of b - however there is no such global. To use the method f1 of self (an instance of Note) as the action, you need to explicitly refer to it as self.f1. (Unlike e. g. in Java, where f1 inside a class translates to this.f1.)

        action functions also need to take a single parameter, sender, which is the UI object that calls the function. f1 currently doesn't have that, meaning that you'll get an exception when the Button tries to run its action.

        1 Reply Last reply Reply Quote 0
        • ccc
          ccc last edited by

          Unfortunately, an exception is NOT thrown but instead the action just fails to get called silently :-(

          A minimal working version:

          import ui
          class Note(ui.View):
              def f1(self, sender):  # adding the sender is key
                   print('hello ' + sender.title)
              def f2(self):
                   b = ui.Button(title='OK')
                   b.action = self.f1
                   self.add_subview(b)
          c = Note()
          c.present()
          c.f2()
          
          1 Reply Last reply Reply Quote 0
          • donnieh
            donnieh last edited by

            Yes, the silent exception is what confused me. I think all your help explained it well. Thank you.

            What if with the example above I wanted to call f1 independently (which now contains the sender argument)? When I try the code below it has an error:

            c.f1() #this cause argument error

            c.f1(0) # this works but why?

            1 Reply Last reply Reply Quote 0
            • ccc
              ccc last edited by

              c.f1(0) does NOT work but instead it throws an AttributeError because an int does not have a .title attribute.

              My recommendation would be that you write:

              def f1(self, sender=None):  # added a default value for sender
                  if sender:
                      print('hello ' + sender.title)  # called as an action
                  else:
                      print('hello, world!')          # called as a method
              
              # [ ... ]
              
              c.f1()  # called as a method with no "sender" parameter
              
              1 Reply Last reply Reply Quote 0
              • donnieh
                donnieh last edited by

                Excellent, good info. Thank you.

                1 Reply Last reply Reply Quote 0
                • dgelessus
                  dgelessus last edited by

                  When using None as a default value, it's best to check for None itself (if arg is None), instead of relying on its falseyness (if not arg). In this case it's unlikely that sender will ever be something that is falsey, but in other cases this can be problematic. For example 0 is falsey, and when writing a function that deals with numbers you don't want 0 to be considered as "no argument given".

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post
                  Powered by NodeBB Forums | Contributors