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.


    ui centering

    Pythonista
    3
    14
    7408
    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.
    • boo
      boo last edited by

      Move the commented line to the second button.center and the button moves. Why?presumedly due the the .width and .height statements.....

      import ui
      		
      v = ui.View()
      
      
      v.present('full_screen')
      button = ui.Button (title='button')
      v.add_subview(button)
      
      button.background_color = 'white'
      #button.center =(100,100)
      button.width= 360
      button.height=100
      button.center=(100,100)```
      1 Reply Last reply Reply Quote 0
      • boo
        boo last edited by

        Horribly worded question. Lets try again.

        Why does:

        button.center =(150,150)
        button.width = 200
        button.heigth= 75
        

        And

        button.width = 200
        button.heigth= 75
        Button.center(150,150)
        
        

        Result in markedly different button positions?

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

          Although you can place a button using the center, its position is still defined by the upper left corner, unless you have flex set. Though Flex I think just affects what happens when parent view gets resized.

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

            Took me a while to understand it's based on THE BUTTON'S upper left corner. Thanks. The word "center" threw me off.

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

              @boo , your example is a little strange as far as I can see.
              Eg. If you do, button.center = v.bounds.center() would make sense to me. Normally, you want to position a item within another item. center is just a tuple(x,y) of the objects center.
              Possibly I am missing some thing, but I don't think so.

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

                I simply want to position a button at a predictable position on screen (x,y) and have it stay there. What am i doing wrong?

                Phuket2 2 Replies Last reply Reply Quote 0
                • Phuket2
                  Phuket2 @boo last edited by Phuket2

                  @boo , the below is using flex. If you change the size or the style, the button is always centered. The best way to understand flex is to use the designer in Pythonista (Create a UIFile).

                  # Pythonista Forum - @Phuket2
                  import ui
                  
                  class MyClass(ui.View):
                      def __init__(self, *args, **kwargs):
                          super().__init__(*args, **kwargs)
                          self.make_view()
                          
                      def make_view(self):
                          btn = ui.Button(frame=(20, 20, 100, 32))
                          btn.border_width = .5
                          btn.title = 'hello'
                          btn.bg_color = 'orange'
                          btn.corner_radius = 6
                          btn.tint_color = 'white'
                          btn.center = self.bounds.center()
                          btn.flex = 'lrtb'
                          self.add_subview(btn)
                  
                  if __name__ == '__main__':
                      w, h = 900, 800
                      f = (0, 0, w, h)
                      style = 'sheet'
                      
                      mc = MyClass(frame=f, bg_color='white')
                      mc.present(style=style, animated=False)
                  

                  Edit: if you remove the line
                  btn.center = self.bounds.center()
                  The button will stay in it's position based on the frame passed. But the flex attr is making that possible.

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

                    @boo here is a slightly different way. It's not using flex, it's using the layout callback(look at custom views in the help file). Is also a valid way to position your objects in a view. Ui Module is so flexible. Maybe the flexibly gives the idea it's hard. But it's not really. Everything is so well constructed, it normally just works very well.

                    # Pythonista Forum - @Phuket2
                    import ui
                    
                    class MyClass(ui.View):
                        def __init__(self, *args, **kwargs):
                            super().__init__(*args, **kwargs)
                            self.make_view()
                            
                        def make_view(self):
                            btn = ui.Button(name='my_btn', frame=(20, 20, 100, 32))
                            btn.border_width = .5
                            btn.title = 'hello'
                            btn.bg_color = 'orange'
                            btn.corner_radius = 6
                            btn.tint_color = 'white'
                            #btn.center = self.bounds.center()
                            #btn.flex = 'lrtb'
                            self.add_subview(btn)
                            
                        def layout(self):
                            self['my_btn'].center = self.bounds.center()
                            
                    
                    if __name__ == '__main__':
                        w, h = 330, 600
                        f = (0, 0, w, h)
                        style = 'sheet'
                        
                        mc = MyClass(frame=f, bg_color='white')
                        mc.present(style=style, animated=False)
                        ```
                    Edit: also the last 2 examples should be orientation friendly also.  Not a big deal, but important.
                    1 Reply Last reply Reply Quote 0
                    • boo
                      boo last edited by

                      Thanks for your help.

                      It seems you use:

                      .frame

                      to position the button. On the website, the basic example for Pythonista ui used:

                      button.center

                      Can you explain differences between frame and center attributes, as relates to a subview (in this case a button)

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

                        @boo , hmmm. I will try. It's not easy to say in words though. But the frame is the x, y, width, height of the object. So btn = ui.Button( frame=(0, 0, 100, 32) ) creates a ui.Button with a width of 100 and a height of 32. The x, y will be 0.
                        So if you set a button for example as above, you can adjust the x, y, width, height in subsequent calls.
                        Eg.
                        btn.x = 100
                        btn.y = 150
                        btn.width = 400 etc..
                        So setting the frame is just a expedient way to set the 4 attrs (x, y, width, height) at one time.

                        Normally it's best to refer to the area/Rect/interior of an ui object by its bounds. Create a ui object with frame and refer to the interior of the object with bounds. For a button for example, the frame and bounds are equal I think. But a ui.View that has a menu for example the frame and bounds will be different. But what is nice, all the ui objects are subclassed from ui.View (almost all) , so you can just use the same technique to refer to bounds or frame. It should just work.
                        Sorry if the above is not clear. Not easy to explain

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

                          Thanks again. Looks like the example provided in the docs had me using button.center, button.height and button.width, instead of just button.frame.

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

                            @boo , I understand what you mean. The example is just one way to do it. I am sure in a few days this will be meaningless to you. It will become second nature to you.

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

                              button.center is a shortcut for button.frame.center, and is the coordinate of the center of the button inside the superview's coordinate system.

                              button.height is a shortcut for button.frame.size.height

                              Here are the basic rules (so you predict what happens). a view's positionis defined by its top left point, and a width and height. If you change width or height, the top left corner stays put.
                              (there is not really a way to say, i want to position using the center, or bottom left, etc, so the convention is, top left)

                              Now, if you want to expand about the center, one approach is to simply store the center location and set it back again

                              oldcenter=btn.center 
                              btn.width=150
                              btn.center=oldcenter
                              

                              Another thing that confuses most people is the difference between frame and bounds. It toom me a long time to understand... frame refers to your position in your parent's coordinate system (i.e relative to your superview's top left corner). bounds refers to your position in your OWN coordinate system. So, if you want to center a button inside another view, you use

                              view.add_subview(btn)
                              btn.center = view.bounds.center 
                              

                              (btn.center refers to btn.frame.center, so is in the super view coordsys, and in this case we want it to match the superview center).

                              Now, if you want to KEEP the centers aligned when the screen rotates, you would use flex, which is how you tell the system whether you intended to place your button really at a particular pixel value, or are more interested in the relative relationship.
                              adjusting bounds also becomes important when you start dealing with ui.Transforms.

                              1 Reply Last reply Reply Quote 1
                              • boo
                                boo last edited by

                                Thanks for the replies. It is becoming much clearer.

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