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.


    Need UI layout help

    Pythonista
    2
    4
    4236
    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.
    • nerdtron
      nerdtron last edited by nerdtron

      I’m trying to create a simple UI in Pythonista for my iPhone 6.

      I’d like to have a single line text box and a button at the top of the screen. The button should be at the upper right and be sized to fit the button’s name text.

      The text box should be the same height as the button and be located to the left of the button and fill the remaining width. I will then fill the remainder of the screen with a SceneView (not yet added).

      The idea is that you can type some text into the text field and then click the button to apply the text to the scene. I would rather not use a layout file and keep it all in a single script file so I’m trying to do it from code.

      I’ve experimented with this using the UI module docs but can’t get it quite working.

      Here’s what I have. Any suggestions on how to get this to do what I want?

      import ui

      view = ui.View()
      view.name = 'test UI'
      view.background_color = 'black'

      r = ui.Button(title='Add Item')
      r.background_color = 'orange'
      r.flex = 'BL'
      view.add_subview(r)

      s = ui.TextField()
      s.flex = 'BR'
      view.add_subview(s )

      view.present('fullscreen')

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

        @nerdtron, I think the below gives you what you want. I didn't try and get your flex values correct. If you look in the ui.designer, this will help get the settings correct. But you still need to size and position your ui objects for flex to work. Hope it helps.
        Also the + 2 and +4 etc in the code is for some margins between the view frame and the ui objects.

        import ui
        
        view = ui.View()
        view.name = 'test UI'
        view.background_color = 'black'
        
        r = ui.Button(title='Add Item', bg_color='orange',
                      width=100, height=100, corner_radius=6)
        r.size_to_fit()          # resizes the button, but a little tight
        r.width += 4             # add a few extra pixels
        
        # using get_window_size()[0], could use ui.get_screen_size()[0]
        # get_window_size should work on split screens also
        r.x = ui.get_window_size()[0] - r.width - 2 # returns a tuple (w,h)
        r.y = 2
        #r.background_color = 'orange'
        #r.flex = 'BL'
        view.add_subview(r)
        
        s = ui.TextField(width=r.frame.min_x - 4,
                         height=r.height)
        s.x = 2
        s.y = 2
        #s.flex = 'BR'
        view.add_subview(s)
        s.begin_editing()        # This gets the text field ready for input.
                                 # You can comment this out, if you dont want
                                 # it to behave like this
        view.present('fullscreen')
        
        1 Reply Last reply Reply Quote 0
        • nerdtron
          nerdtron last edited by

          @Phuket2 thank you very much for the reply and help! Been tied up with other stuff and so have been delayed in getting back to this. I gave that a try and it looked great! I'm curious, though, any thoughts on how to set it up so that when you rotate the device its still correct? I see you're not using flex and from the docs it seems that this is how dynamic layout is normally done. Maybe its a matter of just re-computing using your code when the orientation changes?

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

            @nerdtron , no problems. I think for this example that flex would be the best and easiest. However, when I tried doing it, I had a brain freeze! Its been a long time since I have done it. Pls dont take that as it is hard to do. Once you have it in your head, normally its simple.
            I am sure someone else here will chime in with the correct way to set the flex settings.

            The example I have put below is still a good a good way to know. Its using a custom view. One of the callbacks you get when you have a Custom View Class is layout. Its called by the ui automatically (if you have a method called layout) when you need to respond to changes in your views height or width. Its worth having a read through the docs about Custom Views.
            They are easy to make and give you a lot more flexibility and some extra functionality.

            Anyway, I hope this also helps

            import ui
            
            class MyClass(ui.View):
                def __init__(self, *args, **kwargs):
                    super().__init__(*args, **kwargs)
                    # create the field and button
                    self.in_fld = ui.TextField()
                    self.post_btn = ui.Button(title='Add Item',
                                              bg_color='orange',
                                              corner_radius=6,
                                              action=self.btn_action,
                                              )
                                              
                    # do some static adjustments to button and field properites
                    # properties that we dont need to calculate in layout
                    self.post_btn.size_to_fit()
                    self.post_btn.width += 4
                    self.post_btn.y = 2
                    
                    self.in_fld.x = 2
                    self.in_fld.y = 2
                    self.in_fld.height = self.post_btn.height
                    
                    self.add_subview(self.in_fld)
                    self.add_subview(self.post_btn)
                    
                def btn_action(self, sender):
                    # just to show its working append '@' to the in_fld text
                    self.in_fld.text += '@'
                    
                def layout(self):
                    '''
                    This method is called by the ui automatically when required,
                    such as orientation change.
                    '''
                    
                    # only need to adjust the width of the fld and the x pos
                    # of the btn for this case
                    self.in_fld.width = self.width - self.post_btn.width - 6
                    self.post_btn.x = self.in_fld.frame.max_x + 2
                    
            if __name__ == '__main__':
                mc = MyClass()
                mc.present()
            
            '''
            This would also work as expected    
            if __name__ == '__main__':
                f=(0, 0, 320, 480)
                mc = MyClass(frame=f)
                mc.present('sheet')
            '''
            
            1 Reply Last reply Reply Quote 0
            • First post
              Last post
            Powered by NodeBB Forums | Contributors