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.
[Share] Creating grid for using with ui
-
Sorry, this has been done to death. By me also before. It's just about a small function (get_grid_rc) to create a grid to use with ui.Views. But its always worth bring up I think as there are always new users.
Grids can be represented/determined in many ways depending on your needs. I think the one I have done here is a pretty common need. Unfortunately the test code around the function sort obscures how simple it is. I am not saying this is the best way to do this btw. It's just a way. Again, to try and keep this simple, I did not deal with full screen. It's not thats its so difficult, but different ways to handle that case. Anyway, I hope someone finds it useful.import ui ''' get_grid_rc, can be a handy snippet to get a list of ui.Rects for your view, given a width, height, num rows and num cols. When doing ui stuff you often need this type of functionality. I am sure its not the fastest in speed... Just want some small function that does not eclipse your code. w & h could be evaluated in the list comp, removing a line, but thats seems like it would be a step too far Also, get_grid_rc is not dealing with divide by zero errors. Expects you pass valid params. eg. all params need to be non-zero (positive)! While returning ui.Rects here, could easily change it to return a list of ui.Buttons etc... However seems like a list of ui.Rects is the best for an example. As simple as this example is, it can be useful in many ways. eg. you could call this in a custom views layout method to resize objects. ''' def get_grid_rc(width, height, rows, cols): ''' returns a single linear list of ui.Rects. l[0] will be the most top left rect. l[-1] will be most bottom right rect. ''' w, h = (width / cols, height / rows) return [ui.Rect(w * j, h * i, w, h) for i, _ in enumerate(range(rows)) for j, _ in enumerate(range(cols))] if __name__ == '__main__': f = ui.Rect(0, 0, 320, 480) v = ui.View(frame=f) # simple test action callback for our ui.Buttons. All use this func. def btn_action(sender): print(sender.title) # get the grid and use it as you like. I have used it to add ui.Buttons # to a view. 6 rows x 7 columns for the size of the whole view. # this is a normal grid to make month view on a calender r_grid = get_grid_rc(v.frame.width, v.frame.height, 6, 7) # iterate over the r_grid with enumerate. each iteration we get the index, # and the ui.Rect. for i, r in enumerate(r_grid): btn = ui.Button(name=str(i), title=str(i), bg_color='cornflowerblue', border_width=.5, border_color='white', tint_color='black', action=btn_action) btn.frame = r v.add_subview(btn) v.present(style='sheet', animated=False)
-
import ui ''' get_grid_rc, can be a handy snippet to get a list of ui.Rects for your view, given a width, height, num rows and num cols. When doing ui stuff you often need this type of functionality. I am sure its not the fastest in speed... Just want some small function that does not eclipse your code. w & h could be evaluated in the list comp, removing a line, but thats seems like it would be a step too far Also, get_grid_rc is not dealing with divide by zero errors. Expects you pass valid params. eg. all params need to be non-zero (positive)! While returning ui.Rects here, could easily change it to return a list of ui.Buttons etc... However seems like a list of ui.Rects is the best for an example. As simple as this example is, it can be useful in many ways. eg. you could call this in a custom views layout method to resize objects. ''' def get_grid_rc(width, height, rows, cols): ''' a generator of frame tuples. l[0] will be the most top left rect. l[-1] will be most bottom right rect. ''' w, h = (width / cols, height / rows) return ((w * j, h * i, w, h) for i in range(rows) for j in range(cols)) if __name__ == '__main__': f = ui.Rect(0, 0, 320, 480) v = ui.View(frame=f) # simple test action callback for our ui.Buttons. All use this func. def btn_action(sender): print(sender.title) # get the frames and use them as you like. I have used it to add # ui.Buttons to a view. 6 rows x 7 columns for the size of the whole view. # this is a normal grid to make month view on a calender frames = get_grid_rc(f.width, f.height, 6, 7) # iterate over the frames with enumerate. each iteration we get the index, # and the frame tuple. for i, frame in enumerate(frames): btn = ui.Button(name=str(i), title=str(i), action=btn_action, bg_color='cornflowerblue', border_width=.5, border_color='white', tint_color='black') btn.frame = frame v.add_subview(btn) v.present(style='sheet', animated=False)
-
@ccc , I had thought about using a generator. In my example I am just iterating over them so basically disgarding them, so the generator approach makes more sense. In the event you wanted to keep them around then the list works. Regardless I will update my snippet to yours, I can see I stupidly used enumerate unnecessarily. Makes me glad I posted it now. Nice to have some of these so called simple functions nailed down. One of the reasons I screwed it up is because I had it stored as a snippet without using comprehension. I need to slow down and think sometimes.
-
Staring at someone else's code and optimizing it is so much easier then actually writing new code. I can do the former while riding the subway but the latter takes both time and focus. Please keep up the great work... I still sense that you have a great hotel calendaring app in the back of your head that informs many of your examples.
-
@ccc, the hotel app idea is dead. My friend that I wrote the Excel/VBA version for is not in the hotel business anymore. We are Actualling sharing a nice big house together now in Pattaya. A Danish guy, we have been friends for many years. It's a little bit like the old show the odd couple, us to living together, but we still have fun :)
So no real push for me to do booking thing any more. But I still would like to make a pretty good calendar picker( I honestly hate the Apple DateTime Picker). I have made some before, but I should be able to make something better now. At least I hope so. The other thing I will get back to is my voting app. I always go wrong, as I try to make frameworks instead of just getting on and coding something with brute force just to get it done. Pretty or not. It's funny I should have those problems at this age. I didn't have it when I was younger. I was very aware and sensitive to commercial realities, get it done and out the door! I guess without that need, it changes you.
Hmmm, just after announcing I should be better. I need to ask something embarrassing. I looked at this last night, for some reason I could not get my head around it.
Below in the generator you modified, I have added x in the return tuple. I can't figure out how to get x to just be a linear counter ie. 0 to (rows * cols)-1.
I have looked at it too long so I have decided to ask....My feeling it should be something simple that can be done in place and should not be apart of the comp loops....
just adding x doesn't make much sense as it appears below, but makes more sense if you are creating objects in the generator rather than a tuple.
Any help appreciated.return ((w * j, h * i, w, h, x) for i in range(rows) for j in range(cols))