How to center container contents

How do I center the contents of a container?
image

I would like that it fits the size of container

That is what I’m trying:

lv_obj_t *pContValues = lv_cont_create(MainCont, NULL);
lv_obj_set_auto_realign(pContValues, true);
lv_obj_align_origo(pContValues, NULL, LV_ALIGN_CENTER, 0, 0);
lv_cont_set_fit2(pContValues, LV_FIT_MAX, LV_FIT_TIGHT);
lv_cont_set_layout(pContValues, LV_LAYOUT_ROW_BOTTOM);

lv_obj_t * labelV1 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV1, "LabelA" );
lv_obj_t * labelV2 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV2, "LabelB");
lv_obj_t * labelV3 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV3, "LabelC");
lv_obj_t * labelV4 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV4, "LabelD");

If I use Pretty layout it works… but that is not what I want

image

try this

lv_obj_t *pContValues = lv_cont_create(MainCont, NULL);
lv_obj_set_auto_realign(pContValues, true);
lv_obj_align_origo(pContValues, NULL, LV_ALIGN_CENTER, 0, 0);
lv_cont_set_fit2(pContValues, LV_FIT_MAX, LV_FIT_TIGHT);
lv_cont_set_layout(pContValues, LV_LAYOUT_ROW_BOTTOM);

lv_obj_t * labelV1 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV1, "LabelA" );
lv_obj_align(labelV1 , NULL, LV_ALIGN_CENTER, 0, 0);

lv_obj_t * labelV2 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV2, "LabelB");
lv_obj_align(labelV2 , NULL, LV_ALIGN_CENTER, 40, 0);

lv_obj_t * labelV3 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV3, "LabelC");
lv_obj_align(labelV3 , NULL, LV_ALIGN_CENTER, 80, 0);

lv_obj_t * labelV4 = lv_label_create(pContValues, NULL);
lv_label_set_text(labelV4, "LabelD");
lv_obj_align(labelV4 , NULL, LV_ALIGN_CENTER, 120, 0);

nop :confused:

https://docs.lvgl.io/latest/en/html/widgets/cont.html?highlight=lv_cont_set_fit2#usage
play with these parameters

The second parameter is the reference object.

lv_obj_align(labelV1 , NULL, LV_ALIGN_CENTER, 0, 0);

Use the parent object instead of NULL (in this case the container).

You may adjust the offset based on the parent width and number of objects in the container.

From the source code documentation

base pointer to an object (if NULL the parent is used). ‘obj’ will be aligned to it.

So NULL should be ok
I tried with the container and didn’t work

I don’t think you can align the individual labels because the container is controlling their position itself.

I am not entirely sure how to do what you are suggesting, since in the past I have opted to lay all my widgets out by hand using lv_obj_align calls. I am having trouble finding a way to get the container to center things on the horizontal axis while simultaneously keeping them in a row.

If your labels are a constant size you could increase the left and right padding on your container to get something closer to what you want.

Another idea is to use two containers. Create a parent container using LV_LAYOUT_COLUMN_MID, then, put your current layout on the child container and set it to shrink to fit its children. I think that might do what you want, though you would need to fiddle with the styling to hide the second container’s border.

I saw after I wrote (

Would you like to point me to and example of your method of doing it?

For cases where an existing container layout happens to do what I want, I just use that. In other cases, I set the object’s position by hand. If I want it to always sit at a relative position to another object, I make use of lv_obj_align.

It’s not the cleanest solution, but it works for me. If you have many display sizes this is significantly more complicated to manage, though.

LVGL 8.0 is coming soon and will introduce support for the flexbox and grid layouts used in browsers. I believe these two combined can support just about any layout you would want. That should render this problem largely obsolete.

I see, thanks. The “align to a relative position to another object” I think it is not the case here (as I don’t have the other object to get the center of)

It is not just the display size problem but also the easy way to create the layout. It may happen if I change some size or position of an object I will have to adjust the positions of the others.

I came from a QT background so I was expecting a similar behavior or functionalities (maybe I was expecting too much :stuck_out_tongue: )
QT also has that “springs” thing to adjust / force the layout.

I came with a solution, not perfect, that is, I created a container for each label and I manually set the size of the container (that I calculate based on screen size or parent size). That way I manage to manually “adjust” the placement of the labels centered, each one on its own centered container.

What do thing on this way of doing?

Its ok to create multiple containers like this?

In your original post, it is hard to tell what is the desired outcome. The two images examples appear to be of what you do NOT want? Can you post a view of what the desired outcome is? Also, is your use case specifically for 4 labels, or are you just using 4 as an example and you want it to be for x labels?

I just give the example of 4 labels.

Here is a mock-up of what I’m looking to do (consider that they are all equally spaced, centered on each equal space size of the container):
image

Ok, thanks. The alignment looks to be how the tab bar appears on a tab view, via a button matrix, divided into n even sections with the text centered per section. If your “container within a container” approach works for you, I’d use that, I do a lot of manual layout with lv_obj_align, but I can’t think of anything right now that would be simpler

1 Like