Инструменты пользователя

Инструменты сайта


products:pussy:other:dev_propertycontainer_gui

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
products:pussy:other:dev_propertycontainer_gui [2023/12/09 16:37] – [Решаем задачу] ironmeshproducts:pussy:other:dev_propertycontainer_gui [2023/12/13 14:54] (текущий) – внешнее изменение 127.0.0.1
Строка 1: Строка 1:
 ====== Разработка интерфейса для Контейнера Свойств ====== ====== Разработка интерфейса для Контейнера Свойств ======
  
-FIXME 
  
-В данном уроке я расскажу как разработать альтернативный интерфейс для Контейнера свойств, по умолчанию он генерирует интерфейс единым списком без группировки, если свойств немного, то этого будет вполне достаточно, но если их десятки или даже больше сотни, то таким интерфейсом будет пользоваться не слишком удобно, также может возникнуть желание добавить дополнительные функции, например, сортировка или фильтр и т.п.  Ниже показана предопределенная форма+В данном уроке я расскажу как разработать альтернативный интерфейс для [[:products:pussy:concepts:propertycontainer|Контейнера свойств]], по умолчанию он генерирует интерфейс единым списком без группировки по разделам и прочего, если свойств немного, то этого будет вполне достаточно, но если их десятки или даже сотни, то таким интерфейсом будет пользоваться не слишком удобно, также может возникнуть желание добавить дополнительные функции, например, сортировкафильтр и т.п. Ниже показана предопределенная форма вывода свойств
  
 {{  :products:pussy:screenshots:2023-09-17_14_14_34-configurate_plugin_properties_demo.jpg?400  |Дефолтный интерфейс Контейнера свойств}}Подробнее о концепции свойств читайте [[:products:pussy:concepts:propertycontainer|здесь]]. {{  :products:pussy:screenshots:2023-09-17_14_14_34-configurate_plugin_properties_demo.jpg?400  |Дефолтный интерфейс Контейнера свойств}}Подробнее о концепции свойств читайте [[:products:pussy:concepts:propertycontainer|здесь]].
Строка 36: Строка 35:
  
 </code> </code>
- 
-===== искусственный разграничитель ===== 
  
  
 заметьте, что после определения класса метод //generate_properties()// нужно вызвать, чтобы свойства были созданы. Теперь, можно посмотреть как будет выглядеть дефолтная форма с сгенерированными свойствами заметьте, что после определения класса метод //generate_properties()// нужно вызвать, чтобы свойства были созданы. Теперь, можно посмотреть как будет выглядеть дефолтная форма с сгенерированными свойствами
  
-{{  :products:pussy:screenshots:lessons:def_propcontainer_gui_1.jpg?200  }}выглядит она не очень презентабельно, тут собрано порядка 500 свойств, пользователю было бы непросто здесь разобраться. Напомнючто имя свойства определяет, на какую страницу оно попадет, то есть свойства с префиксом "_s1" попадают на первую страницу, с "_s2" на вторую и так далее. +{{  :products:pussy:screenshots:lessons:def_propcontainer_gui_1.jpg?200  |def_propcontainer_gui_1.jpg}}выглядит она не очень презентабельно, тут собрано порядка 500 свойств, на практике с этим было бы трудно работать. 
-Для у PropertyContainer за вывод интерфейса отвечает метод render_layout()+ 
 +Напомню, что в новом интерфейсе имя свойства определяет, на какую страницу оно попадет, то есть свойства с префиксом "s1" попадают на первую страницу, с "s2" на вторую и так далее. У [[:products:pussy:api:pyub:types:propertycontainer|]] за вывод интерфейса отвечает метод //[[http://wiki.mig-ironmesh.ru/products;pussy;api;pyub;types;propertycontainer#render_layout|render_layout()]]// , а метод //[[http://wiki.mig-ironmesh.ru/products;pussy;api;pyub;types;propertycontainer#retranslate|retranslate()]] // отвечает за перевод отображаемой информации, Менеджер автоматически вызывает данные методы, поэтому //retranslate() // не нужно вызывать в коде, как это делается в СвойствахЕсли перевод не нужен, то заполнение интерефейса можно произвести в методе //render_layout()// а в методе //retranslate() // вписать ключевое слов//о pass//. 
 + 
 +Итак, в итоге у меня получился следующий код для методов// render_layout() // и// retranslate()// 
 + 
 + 
 +<code python> 
 +@classmethod 
 +    def render_layout(cls) -> QToolBox: 
 +        cls._lable_list = {} 
 +        cls._tool_box = QToolBox() 
 + 
 +        def render_page(suffix:str) ->QScrollArea: 
 +            scroll_area = QScrollArea() 
 +            scroll_area.setWidgetResizable(True) 
 +            widget_content = QWidget() 
 +            layout = QFormLayout(widget_content) 
 +            layout.setVerticalSpacing(15) 
 +            layout.setLabelAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) 
 +            row: int = 0 
 +            for key, prop in cls.__annotations__.items(): 
 +                if not key.endswith(suffix): continue 
 +                cls._lable_list[key] = QLabel() 
 +                cls._lable_list[key].setWordWrap(True) 
 +                layout.setWidget(row, QFormLayout.LabelRole, cls._lable_list[key]) 
 +                layout.setWidget(row, QFormLayout.FieldRole, prop.get_input_widget()) 
 +                row += 1 
 +            scroll_area.setWidget(widget_content) 
 +            return scroll_area 
 + 
 +        for i in range(1, 6): 
 +            cls._tool_box.addItem(render_page(f"s{i}"), ""
 + 
 +        return cls._tool_box 
 + 
 +    @classmethod 
 +    def retranslate(cls) -> None: 
 +        for key, label in cls._lable_list.items(): 
 +            label.setText(cls.get_property(key).get_name()) 
 +            cls.__annotations__[key].retranslate() 
 + 
 +        for i in range(cls._tool_box.count()): 
 +            cls._tool_box.setItemText(i, QCoreApplication.translate("properties", f"Section {i+1}")) 
 +</code> 
 + 
 +А вот так выглядит новый интерфейс, уже намного лучше. Это только один из вариант группировки свойств по разделам, также можно для таких целей использовать виджеты: [[:products:pussy:other:qtabwidget|QTabWidget]], [[:products:pussy:other:qstackedwidget|QStackedWidget]] совместно с виджетом для выбора элементов, например, [[:products:pussy:other:qlistwidget|QListWidget]], [[:products:pussy:other:qcombobox|QComboBox]] и другие.{{  :products:pussy:screenshots:lessons:def_propcontainer_gui_2.jpg?200  |def_propcontainer_gui_2.jpg}}Теперь, попробую объяснить код, который я написал, начну с метода// render_layout()//, в самом начале определяем словарь //_lable_list//, в котором будут содержаться все подписи для свойств, которые представляют из себя экземпляры виджета QLable, а в переменной //_tool_box // будет находиться экземпляр [[:products:pussy:other:qtoolbox|QToolBox]], обе эти переменные сохраняются в классе, чтобы был к ним доступ из других методов. Затем я ввел вспомогательную вложенную функцию //render_page()//, которая отбирает свойства, имена которых имеют указанный суффикс и упаковывает их в форму ([[:products:pussy:other:qformlayout|QFormLayout]]) внутри виджетакоторый в свою очередь вложен в область ([[:products:pussy:other:qscrollarea|QScrollArea]]), затем функция возвращает сформированный интерфейс; в цикле //for // производится обход всех Свойств, которые хранятся в словаре //_ _annotations_ _//, имена свойств, которые не имеют нужный суффикс игнорируются, а те что соответствуют, у них берется виджет для ввода методом //get_input_widget()//, затем он добавляется в форму layout([[:products:pussy:other:qformlayout|QFormLayout]]) в правый столбец (роль //[[:products:pussy:other:qformlayout|QFormLayout]].[[:products:pussy:other:fieldrole|FieldRole]]), // а подписи для свойств (экземпляры QLable) помещаются в левый столбец (роль //[[:products:pussy:other:qformlayout|QFormLayout]].[[:products:pussy:other:labelrole|LabelRole]]//). Заметьте, что для подписей Свойств текст не устанавливается, это будет сделано позднее. В конце производится добавление страниц в //_tool_box//, для этого вызыватся метод //addItem()//, которому передается результат функции //render_page(), // которой передаются строки с суффиксами, определенные нами ранее. 
 + 
 +В методе //retranslate() // выполняется перевод отображаемой информации, а именно: подписи разделов для //_tool_box//, подписей Свойств и самих Свойств. Для перевода подписей свойств мы обходим все элементы в //_lable_list // и устанавливаем тексткоторые вернет метод свойства //get_name()//, заметьте, что в качестве ключей использованы имена свойств в контейнере; также у каждого свойства вызывается метод //retranslate()//, чтобы перевести отображаемую информацию; в конце производится обход всех элементов в //_tool_box// и устанавливает их текст на предопределенный, для поиска перевода используется команда //[[:products:pussy:other:qcoreapplication|QCoreApplication]].translate(<контекст>, <текст>).// 
 + 
 +Подытожу все вышесказанное. Для того чтобы определить свой вариант интерефейса нужно переопределить всего 2 метода:// render_layout() // и// retranslate()//, первый метод должен вернуть виджет с сгенерированным интерфесом, а второй выполнить перевод отображаемой информации. Элементы для интерефейса мы извлекаем из самих свойствызовом метода //get_input_widget(), // а текст с именем свойства нам вернет метод //get_name()//; сами свойства хранятся в классе, в поле //_ _annotations_ _,  // которое представляет из себя обычный словар, где ключ - идентификатор свойства, а значение - ссылка на само свойство.
  
-Ну, вот и все, урок по разработке собственного класса свойства подошел к концу, как вы могли убедиться это очень простой процесс, который не займет много времени и сил, но перед использованием не забывайте тестировать свой код. Если что-то не понятно, то можно задать вопрос в [[http://discord.gg/JD5yKPrKCk|Discord]].+Ну, вот и все, урок по разработке альтернативного интерфейса для Контейнера свойств подошел к концу, как вы могли убедиться это очень простой процесс, который не займет много времени и сил, при наличии опыта разработки интерфейсов, если опыта мало, то можно сверстать его в [[:products:pussy:other:qtdesigner|QtDesigner]], а затем посмотреть как устроен код и перенести его в свой проект с некоторыми изменениями или импортировать его целиков. Кстати, перед использованием не забывайте тестировать свой код. Если что-то не понятно, то можно задать вопрос в [[http://discord.gg/JD5yKPrKCk|Discord]].
  
  
products/pussy/other/dev_propertycontainer_gui.1702129063.txt.gz · Последнее изменение: (внешнее изменение)