Как привязать к нажатию кнопки вызов функции, а не оператора

К нажатию кнопки в пользовательском интерфейсе обычно привязывают вызов нужного оператора. Однако часто действия, которые нужно выполнить при нажатии на кнопку, достаточно просты и не требуют оформления в виде отдельного оператора. Да и забивать стек зарегистрированных операторов множеством специфических операторов, рассчитанных на выполнение одной конкретной узкоспециализированной функции не имеет смысла. Гораздо удобнее было бы связать нажатие кнопки с вызовом отдельной функции, однако API Blender позволяет связывать кнопки только с вызовом оператора.

Обойти проблему создания отдельного оператора под каждую кнопку можно, воспользовавшись тем, что оператор можно вызывать с указанием входных параметров.

Для примера создадим простейший оператор:

Определим в нем несколько нужных нам функций:

  • clear_scene — для удаления всех объектов из сцены
  • add_cube — для добавления в сцену куба
  • add_sphere — для добавления в сцену сферы.

Теперь самое главное — добавим в оператор входной параметр action перечислимого типа EnumProperty:

в зависимости от значения которого будем вызывать нужную функцию. Первым в списке идет текстовый идентификатор, который и будет передаваться в оператор при вызове.

Добавим в функцию execute оператора условие для вызова нужной функции в зависимости от значения входного параметра acton:

Теперь если оператор будет вызван с параметром «CLEAR» — будет выполнена его функция clear_scene, с параметром «ADD_CUBE» — будет выполнена функция add_cube и т.д.

Полный код оператора выглядит так:

В N-панели создадим свою вкладку с пользовательской панелью для размещения наших кнопок:

В методе draw созданного класса панели мы определили три кнопки «Clear scene», «Add cube» и «Add sphere», привязав к каждой из них вызов созданного ранее оператора, но для каждой — со своим параметром action равным «CLEAR», «ADD_CUBE» и «ADD_SPHERE». В итоге при нажатии на кнопку вызывается один и тот же оператор, но с разным входным параметром, в результате чего оператор выполняет разные функции в соответствии с полученным значением этого параметра.

Финальный код выглядит следующим образом:

В результате мы получили механизм для вызова различных функций по нажатию кнопок без необходимости создавать и регистрировать для каждой из кнопок отдельный оператор.