Часто элементы интерфейса, размещаемые в пользовательских панелях, не соответствуют друг другу по размерам, в результате чего общая компоновка панели выглядит не красиво. В качестве наглядного примера создадим пользовательскую панель и разместим на ней кнопку оператора и текстовое поле ввода.
Выровнять размеры кнопки и поля ввода здесь напрашивается само собой.
Код создания такой панели имеет вид:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import bpy from bpy.types import Panel from bpy.utils import register_class, unregister_class class TEST_PT_panel(Panel): bl_idname = 'TEST_PT_panel' bl_label = 'Test' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Test' def draw(self, context): layout = self.layout row = layout.row() row.label(text='Add mesh') row.operator('mesh.primitive_cube_add', text='Cube') layout.prop(bpy.data.worlds['World'], 'name', text='World name') def register(): register_class(TEST_PT_panel) def unregister(): unregister_class(TEST_PT_panel) if __name__ == '__main__': register() |
Формирование внешнего вида панели – расположения кнопок и других элементов, производится в функции draw.
Все элементы интерфейса располагаются на общей подложке layout (self.layout).
Команда row класса UILayout
1 |
row = layout.row() |
формирует строку на которой располагаются друг за другом два элемента – текстовый лейбл с надписью “Add mesh” и кнопка оператора для создания в сцене куба.
1 2 |
row.label(text='Add mesh') row.operator('mesh.primitive_cube_add', text='Cube') |
Свойство “World name” располагается на следующей строчке т.к. вызывается не для созданной строки row а для всего layout.
1 |
layout.prop(bpy.data.worlds['World'], 'name', text='World name') |
Для того, чтобы красиво расположить элементы управления и выровнять размеры кнопки и поля свойства, нужно разбить весь layout на две вертикальные колонки. В левой мы будем писать текст, в правой – размещать элементы управления.
Команда split класса UILayout разбивает layout на колонки в пропорциональном соотношении по ширине, определяемым параметром factor. Создадим такое разбиение:
1 |
split = layout.split(factor=0.25) |
Команда возвращает объект split на котором мы далее сформируем сами колонки:
1 2 |
col_1 = split.column() col_2 = split.column() |
Получив колонки “col_1” и “col_2” разместим на первой (левой) текстовые лейблы, а на второй (правой) – кнопку и поле.
Для оператора:
1 2 |
col_1.label(text='Add mesh') col_2.operator('mesh.primitive_cube_add', text='Cube') |
и для поля ввода:
1 2 |
col_1.label(text='Word name') col_2.prop(bpy.data.worlds['World'], 'name', text='') |
В результате элементы управления расположены на нашей панели гораздо аккуратнее.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import bpy from bpy.types import Panel from bpy.utils import register_class, unregister_class class TEST_PT_panel(Panel): bl_idname = 'TEST_PT_panel' bl_label = 'Test' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Test' def draw(self, context): layout = self.layout split = layout.split(factor=0.25) col_1 = split.column() col_2 = split.column() col_1.label(text='Add mesh') col_2.operator('mesh.primitive_cube_add', text='Cube') col_1.label(text='Word name') col_2.prop(bpy.data.worlds['World'], 'name', text='') def register(): register_class(TEST_PT_panel) def unregister(): unregister_class(TEST_PT_panel) if __name__ == '__main__': register() |