К сожалению, интерфейс Blender не поддерживает перенос строк и многострочный вывод в текстовых полях. Слишком длинные для показа на панели текстовые строки обрезаются. Однако, текст в несколько строк все же можно вывести на панель интерфейса, используя несколько текстовых элементов вместо одного.
Для начала создадим простейшую панель в N-панели окне вьюпорта 3D Viewport и разместим на ней текстовый элемент label с нужным текстом.
Определим класс панели и зарегистрируем его.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from bpy.types import Panel from bpy.utils import register_class class TEST_PT_private(Panel): bl_idname = 'TEST_PT_test' bl_label = 'MULTILINE TEXT' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'TEST' def draw(self, context): layout = self.layout text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' layout.label(text=text) register_class(TEST_PT_private) |
Выполнив данный код нажатием на кнопку “Run Script”, мы создадим новую панель “MULTILINE TEXT” на которой будет размещен текст “Loren ipsum…” в одну строку.
Для того, чтобы сделать текст многострочным, разобьем его по пробелам с учетом ширины панели на отдельные строки.
Текущую ширину панели в пикселях можно получить из контекста окна.
1 2 3 |
context.region.width # 438 |
Напишем функцию, которая будет разбивать переданную в нее строку текста так, чтобы длина каждой строки не превышала ширины панели. Для разбивки воспользуемся модулем “textwrap”.
1 2 3 4 5 6 7 8 |
import textwrap def _label_multiline(context, text, parent): chars = int(context.region.width / 7) # 7 pix on 1 character wrapper = textwrap.TextWrapper(width=chars) text_lines = wrapper.wrap(text=text) for text_line in text_lines: parent.label(text=text_line) |
В функцию мы передаем три параметра:
- context – контекст окна для определения ширины панели
- text – текст, который нужно показать
- parent – элемент панели интерфейса на который мы будем выводить текст
Модуль “textwrap” разбивает текст не по пикселям, а по символам. Поэтому сначала мы определяем, сколько символов уложится в строку, нужной нам длины (ширина панели). Приблизительно можно взять среднюю ширину символа равную 7 пикселям.
1 |
chars = int(context.region.width / 7) # 7 pix on 1 character |
После чего мы получаем список строк, на которые разделили текст.
1 2 |
wrapper = textwrap.TextWrapper(width=chars) text_lines = wrapper.wrap(text=text) |
Далее по этому списку на родительском элементе мы создаем нужное количество элементов label, в каждом из которых содержится очередная строка текста.
1 2 |
for text_line in text_lines: parent.label(text=text_line) |
Оформив функцию, заменим вывод строки текста в нашей панели на вызов этой функции. Теперь весь текст располагается на панели построчно и даже будет подстраиваться при изменении ширины панели.
Полный код:
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 |
from bpy.types import Panel from bpy.utils import register_class import textwrap def _label_multiline(context, text, parent): chars = int(context.region.width / 7) # 7 pix on 1 character wrapper = textwrap.TextWrapper(width=chars) text_lines = wrapper.wrap(text=text) for text_line in text_lines: parent.label(text=text_line) class TEST_PT_private(Panel): bl_idname = 'TEST_PT_test' bl_label = 'MULTILINE TEXT' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'TEST' def draw(self, context): layout = self.layout text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' _label_multiline( context=context, text=text, parent=layout ) register_class(TEST_PT_private) |