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.


    checking for integers inside of a ui textfield

    Pythonista
    4
    8
    5860
    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.
    • wenchoheelio
      wenchoheelio last edited by

      I'm trying to check if a textfield in my ui has any numbers in it when I press on a button. When I use the same code on a string it works. When I use the code for textfield within a button's action it doesn't work. Please help? Here's what my code is like:

      import ui
      import console
      
      def contains_digits(d):
       for char in d:
        if char.isdigit():
         return True
        return False
      
      test='test3'
      print(contains_digits(test)) #this works - it prints TRUE!
      
      #below always prints failed even though it should print whatever is in the textfield?!
      
      def button_pushed(sender):
        if contains_digits(textfield1):
         print(textfield1)
        print('failed')
      
      v=ui.load_view()
      textfield1 = str(v['textfield1'].text)
      v.present('fullscreen')
      
      1 Reply Last reply Reply Quote 0
      • JonB
        JonB last edited by JonB

        To debug this problem, print textfield when entering button_pushed.
        As a reminder, strings in pythons are their own object, not pointers.

        >a='hello'
        >b=a
        >a='world'
        >print(a==b)
        False
        

        By the way, in case you have never used pdb before, this can really be useful.

        def button_pushed(sender):
           import pdb
           pdb.set_trace()
        

        now, when you push the button, type

        print(textfield)
        print(v['textfield1'].text)

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

          Thanks so much for your help here. It seems that it's a problem with the variable - textfield1

          Doing what you said - textfield1 prints nothing to the console and v['textfield1'].text prints whatever was typed into the textfield

          Do you happen to know anyway in which I can use a variable to print to the console using the button?

          I think I understand the issue from how you've explained it - the variable textfield1 starts of as "" and so even when it changes it's always going to remain as "", in order for me to put it into a variable - I'd have to put it into a variable within the function, when it's already set as whatever the user has set it as.

          I think I may have answered my own question there?

          Phuket2 1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by

            Yep. Just use v['textfield1'].text, or store a refernce to the actual textfield object, then you can print the .text attribute.

            1 Reply Last reply Reply Quote 0
            • Phuket2
              Phuket2 @wenchoheelio last edited by

              @wenchoheelio , below is another way to consider filtering your TextField. Ie using a TextField Delegate. This way you are getting a peek at the key before it makes it into the TextField(you can accept or reject it, by either returning True or False). Below I have just copied the standard Delegate from the Pythonista Documentation. I just modified the textfield_should_change callback.
              I could have deleted all the other methods in the class as in this case I am not using them. They will just do their default behaviour if they are not there. I point that out because the code looks longer and more complicated that it needs to to handle your case. I left them in so it was easy to see the other events you can take control of. Basically meaning you can have a lot of control over the data entry into the TextField.

              Btw, I am looping over the replacement as it maybe a string that is being pasted into the textfield. You can try it by copying say '123456' and pasting it into your field. It will appear. But then try pasting '123456R' into the field, that will not work.

              Hope it helps.

              import ui
              
              class MyTextFieldDelegate (object):
                  def textfield_should_begin_editing(self, textfield):
                      return True
                  def textfield_did_begin_editing(self, textfield):
                      pass
                  def textfield_did_end_editing(self, textfield):
                      pass
                  def textfield_should_return(self, textfield):
                      textfield.end_editing()
                      return True
                  def textfield_should_change(self, textfield, range, replacement):
                      for c in replacement:
                          if not c.isdigit():
                              return False
                      return True
                  def textfield_did_change(self, textfield):
                      pass
              
              class MyClass(ui.View):
                  def __init__(self, *args, **kwargs):
                      super().__init__(*args, **kwargs)
                      self.make_view()
              
                  def make_view(self):
                      tf = ui.TextField(frame=(0, 0, self.width, 32))
                      tf.delegate = MyTextFieldDelegate()
                      self.add_subview(tf)
              
              if __name__ == '__main__':
                  f = (0, 0, 300, 400)
                  v = MyClass(frame=f)
                  v.present(style='sheet', animated=False)
              
              wenchoheelio 2 Replies Last reply Reply Quote 0
              • wenchoheelio
                wenchoheelio @Phuket2 last edited by

                @Phuket2 Thanks, I really appreciate the time you've taken to write this.

                1 Reply Last reply Reply Quote 0
                • wenchoheelio
                  wenchoheelio @Phuket2 last edited by

                  @Phuket2

                  super().init(*args, **kwargs)

                  I don't fully understand the super() part here. Not sure I really need to understand or use it early on? Also, I understand arguments/parameters - but what's *args, **kwargs ?Does that mean something? Arguments and KW arguments?!

                  (frame=f)

                  What is this code for? It doesn't look like the function requires a parameter? (obviously it does.. I just don't understand it)

                  Thanks.

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

                    @wenchoheelio MyClass is a subclass of ui.View. ui.View already has its own __init__ method, and now we also define an __init__ method in our subclass. By default, our subclass __init__ would completely replace the __init__ from ui.View. This would not be good, because then the code in ui.View.__init__ would never run for our MyClass views, and they would not be set up properly. To avoid this, we call super().__init__(*args, **kwargs), which is (in this case) a shortcut for ui.View.__init__(self, *args, **kwargs). That is, we let ui.View initialize our custom view before we do our own initialization.

                    The *args and **kwargs syntax is used here to pass all arguments from our own __init__ to the superclass __init__. In a function/method definition, *args stands for "accept any number of positional (unnamed) arguments and put them into args as a tuple", and **kwargs stands for "accept any number of keyword (named) arguments and put them into kwargs as a dictionary". In a function/method call, they do basically the opposite, and pass the contents of the given tuple/dictionary as arguments.

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