Hi, I wrote a script that builds a window with dropdowns (in USD Composer 2023.2, scripting it as an extension in python) and would like to add a scrollbar to the middle section with the dropdown rows:
‘Add’ button adds a new row with dropdowns.
I’d like to script this:
(this is a result of using ui.ScrollingFrame but now the ‘Add’ button replaces the existing dropdown row continuously :D , see “I’ve tried” below). Any suggestions?
My code:
def on_startup(self, ext_id):
'''Preset hstack id (same id for dropdowns in each preset hstack)'''
self._hstack_id = 0
'''Holding presets hstacks and their dropdowns'''
self.hstacks_dict : Dict[ui.HStack] = {}
'''Constructing main window'''
self._window = ui.Window("Rendering Selector", width=900, height=270)
with self._window.frame:
with ui.VStack():
with ui.HGrid(height=50): # I'm calling them hstacks everywhere in comments, ended up replacing ui.HStacks with ui.HGrid
ui.Button("Add", clicked_fn=self.add_dropdowns_hstack, width=self.BUTTON_WIDTH, height=self.BUTTON_HEIGHT)
ui.Button("Remove", clicked_fn=self.remove_dropdowns_hstack, width=self.BUTTON_WIDTH, height=self.BUTTON_HEIGHT)
ui.Button("Duplicate", clicked_fn=self.duplicate_dropdowns_hstack, width=self.BUTTON_WIDTH, height=self.BUTTON_HEIGHT)
'''Constructing frame with presets HStacks'''
self.selections_vstack = ui.VGrid(spacing=20)
'''Adds first dropdowns hstack to self.selections_vstack'''
self.add_dropdowns_hstack()
with ui.HGrid(height=50):
ui.Button("Select All", clicked_fn=self.select_all_checkboxes, width=self.BUTTON_WIDTH, height=self.BUTTON_HEIGHT)
ui.Button("Deselect All", clicked_fn=self.deselect_all_checkboxes, width=self.BUTTON_WIDTH, height=self.BUTTON_HEIGHT)
ui.Button("Render Selected", clicked_fn=self.duplicate_dropdowns_hstack, width=self.BUTTON_WIDTH, height=self.BUTTON_HEIGHT)
def add_or_duplicate_dropdowns(self, save_state_id, interior_color_id, exterior_color_id, trim_id, camera_id, checkbox_bool):
with self.selections_vstack:
self.hstacks_dict[self._hstack_id] = {}
self.hstacks_dict[self._hstack_id]["hstack_object"] = ui.HStack(height=30)
self.hstacks_dict[self._hstack_id]["dropdowns_dict"] = {}
with self.hstacks_dict[self._hstack_id]["hstack_object"]:
dropdowns_dict = self.hstacks_dict[self._hstack_id]["dropdowns_dict"]
dropdowns_dict["radiobutton"] = ui.RadioButton(identifier=f"{self._hstack_id}",
radio_collection=self.collection,
width=30,
height=30,
clicked_fn=self.get_selected_radiobutton_int)
dropdowns_dict["save_state"] = ui.ComboBox(save_state_id,
*self.save_state_list,
width=self.DROPDOWN_WIDTH)
dropdowns_dict["interior_color"] = ui.ComboBox(interior_color_id,
*self.interior_color_list,
width=self.DROPDOWN_WIDTH)
dropdowns_dict["exterior_color"] = ui.ComboBox(exterior_color_id,
*self.exterior_color_list,
width=self.DROPDOWN_WIDTH)
dropdowns_dict["trim"] = ui.ComboBox(trim_id,
*self.trim_list,
width=self.DROPDOWN_WIDTH)
dropdowns_dict["camera"] = ui.ComboBox(camera_id,
*self.camera_list,
width=self.DROPDOWN_WIDTH)
dropdowns_dict["checkbox"] = ui.CheckBox(identifier=f"{self._hstack_id}",
alignment=ui.Alignment.BOTTOM)
dropdowns_dict["checkbox"].model.set_value(checkbox_bool)
def add_dropdowns_hstack(self):
self.add_or_duplicate_dropdowns(save_state_id=0,
interior_color_id=0,
exterior_color_id=0,
trim_id=0,
camera_id=0,
checkbox_bool=False)
self._hstack_id += 1
I’ve tried:
- adding “auto_resize=True” to self._window - it works auto-resizing the window, but that’s not the same as a scrollbar
- using ui.ScrollingFrame: - replacing it as my self.selections_vstack instead of a ui.VGrid curiously only allows me to have 1 child/row with dropdowns. Ussing the “Add” button always replaces the 1st row with a new row with default settings in the dropdowns:
self.selections_vstack = ui.ScrollingFrame(height=200,
width=800,
horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_ON,
style={"ScrollingFrame": {
"background_color": cl.set_shade("default"),
"scrollbar_size": 15,
}})
- using ui.TreeView but I haven’t been successful in implementing a model that would work with UI (ui.ComboBox, ui.RadioButton etc) objects.