I would like to align widgets inside two HBoxes horizontally.
import ipywidgets as widgets
but1 = widgets.RadioButtons(options=["foo", "bar"])
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"])
check1 = widgets.Checkbox(description="asdf")
check2 = widgets.Checkbox(description="verylongstringherethisislong")
box_layout = widgets.Layout(
align_items='flex-start',
width='1300px',
justify_content='flex-start'
)
widgets.VBox(
children=[
widgets.HBox(children=[but1, but1, but2, but2], layout=box_layout),
widgets.HBox([check2, check2, check1, check1], layout=box_layout)
]
)
This update to make four columns of RadioButtons with Checkboxes aligned below each column uses a Grid Layout after comments by OP that the fine-tuning necessary with using the margins doesn't seem clean as expected.
Still, the key change of setting indent=False
for the Checkbox widgets is important, see the details below the original reply for more.
import ipywidgets as widgets
but1 = widgets.RadioButtons(options=["foo", "bar"])
but1pt5 = widgets.RadioButtons(options=["foo", "bar"])
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"])
but2pt5 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"])
check1 = widgets.Checkbox(description="asdf", indent=False)
check2 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check3 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check4 = widgets.Checkbox(description="asdf", indent=False)
# Create GridBox layout
grid_layout = widgets.Layout(
display='grid',
grid_template_columns='auto auto auto auto',
grid_gap='10px 10px',
width='1300px',
justify_content='flex-start'
)
# Create GridBox
grid_box = widgets.GridBox(
children=[
but1, but1pt5, but2, but2pt5,
check2, check3, check4, check1
],
layout=grid_layout
)
display(grid_box)
This gets close on my system:
import ipywidgets as widgets
but1 = widgets.RadioButtons(options=["foo", "bar"])
but1pt5 = widgets.RadioButtons(options=["foo", "bar"], layout=widgets.Layout(margin='0 0 0 5px') )
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 4px') )
but2pt5 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 4px') )
check1 = widgets.Checkbox(description="asdf", indent=False)
check2 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check3 = widgets.Checkbox(description="verylongstringherethisislong", indent=False)
check4 = widgets.Checkbox(description="asdf", indent=False)
box_layout = widgets.Layout(
align_items='flex-start',
width='1300px',
justify_content='flex-start'
)
vbox = widgets.VBox(
children=[
widgets.HBox(children=[but1, but1pt5, but2, but2pt5], layout=box_layout),
widgets.HBox(children=[check2, check3, check1, check4], layout=box_layout)
]
)
display(vbox)
Keep in mind some adjustment may still be in order. I doubt these are the real labels, and so you may need to also adjust more. Plus, your system may handle the spacing a little different so some adjustment may be necessary. Hopefully the details I provide below will help in that fine tuning.
UPDATE: speaking of adjustments it was pointed out that you can also use percents for controlling the padding setting. In this case, this is what I found works for substituting in for the lines with the pixel settings for padding:
but1pt5 = widgets.RadioButtons(options=["foo", "bar"], layout=widgets.Layout(margin='0 0 0 0.4%') )
but2 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 0.3%') )
but2pt5 = widgets.RadioButtons(options=["verylongstringherethisislong", "bar"], layout=widgets.Layout(margin='0 0 0 0.2%') )
That seems rather arbitrary, yet it was what I saw produced reasonable results in this situation. I add it because maybe it is resistant to changes in window size, unlike I suspect the pixel settings. Indeed that ability is why the percent setting was suggested here and there the use of the 50%
makes sense because it is centering a checkbox in that case. Unlike here where the values seem very arbitrary.
The key change in my code relative yours, is setting indent=False
for the Checkbox widgets. By default, ipywidgets indents the checkboxes for better alignment with their descriptions. However, here you don't want this as it is causing a major issue with the alignment in your case. Fortunately, the setting indent=False
ensures that the checkboxes are not indented and are aligned with the left edge of their containers.
In your case, just adding that setting indent=False
for the Checkbox widgets gets you 90% of the way there relative your original code.
However, it still isn't aligned even though it is much less dramatic with the indent nixed.
So next I added ,layout=widgets.Layout(margin='0 0 0 1px')
to the Checkbox widget for the Checkbox appearing on the left side of your columns and that addition of a left margin
CSS property of some pixel value via the layout
parameter helped that one in the second column look better aligned. However, I realized the others wouldn't be as easy, and so I switched to adding the left margin to the radio buttons. Doing that I realized, I need to separate these out so that each column has a very similarly setup widget, but an actual different widget that I can adjust independently. So that is why there are more than you had. I could pare down the checkboxes and second set of radio buttons back gain since I moved the margin handling to the radio buttons and the two radio buttons with the long label are the same, but I left them for now since you may need to fine tune. In the end, with your code the margins for the radio buttons just needed values of a few pixels to bring them in line with the unindented checkboxes.