Hello fellow Pythonistas, in this tutorial we’ll find out how to use UILists in our scripts and add-ons. If your users need to handle large amounts (or variable) amounts of data, this is the widget you want.
While you could just use a loop to draw widgets UILists have several benefits over custom-made solutions, like filtering, searching and managing space correctly (less scrolling). It’s also how it’s done throughout the UI, so you can stay consistent with the rest of Blender.
By the way, I’m assuming you already know your way around the BPY and Python. This is an intermediate tutorial.
Define the properties
First we have to create some properties to hold the data on our list first. If we are populating the list with data of our own, we’ll need to define the structure of the items in the list. You don’t need to define an item if you’re using existing datablocks like materials, or textures.
We’ll also need a Collection Property that will hold our list data, and an Integer property to hold the index number. Let’s add them in our register() function.
Make the list widget
Now we can create the actual widget by extending the UIList class. The UIList has one method (that we care about) called draw_item(). This method is called to draw each item in the list and it works pretty much like any other drawing callback in Blender. You can use labels, check boxes, operator buttons, etc.
draw_item() includes several parameters we can use:
data: Object containing the collection property (in our case, the scene)
item: The current item being drawn
icon: Calculated icon for the current item as an integer (could be one of Blender's or an icon for a material/texture/etc. depending on the item)
active_data: Object containing the active property of the collection (in our case, the scene too)
active_propname: The name of the active property (index). In our case, it would be "list_index")
index: Index of the current item (this one is optional)
Don’t forget to register your UIList subclasses, or Blender won’t know about them.
Now we can call it in our UI with the template_list() function.
Let users modify the list
What good is a list if users can’t do anything with it? We’ll let users add, delete and move items up and down. These are the most basic operations, you can easily use them as a template to make your own.
Let’s begin by adding the operators.
The add operator is pretty straightforward. Just call the add() method in the list.
For the delete op we first have to check we have something to delete. We use the poll() method to check that there’s at least one item in the list. The cool thing about using poll() is that you it will also disable the operator button in the ui automatically.
Deleting is done by calling remove() with the list index (which will be whatever we have selected in the ui).
Finally we have to fix the index. If we delete at the end of the list the index will have an invalid value (larger than the length of the list), so we always move it back one position unless it’s zero.
Moving an item around takes some more consideration because we have to make sure the index stays valid.
The move() method allows us to swap items at two different indexes. We only have to figure out which index to swap with. Remember we start counting from zero, increasing downwards.
Finally we call our own move_index() method to change the index while clamping it between 0 and the list length.
Showing data from a list item is easy too, just use the index. Don’t forget to make sure it’s valid though.
The Final code
That’s it guys! You now have a basic but fully functional UIList. If you’re interested in more advanced topics like custom filters you can check the templates in the text editor (templates > python > ui list).