Туториал - создание блокнота в QT Designer
QT - популярная кросс-языковая и кроссплатформенная библиотека для создания графических пользовательских интерфейсов для персональных компьютеров и т.п. Она имеет поддержку тем и стилей, взаимодействия с клавиатуры и все обычные горячие клавиши, а главное, широкое распространение и большое количество инструментов, чтобы облегчить работу с ней.
Сегодня я расскажу вам о QT Designer, графическом инструменте для создания интерфейсов на QT.
Видео Ссылка на заголовок
Подготовка Ссылка на заголовок
Установка QT Designer Ссылка на заголовок
Windows Ссылка на заголовок
Загрузите и установите исполняемый файл QT, найденный в официальном веб-сайте или установите пакеты вроде pyqt5
или pyqt6
для Python при помощи pip.
Затем вам нужно проверить путь установки, найти файл designer.exe
и запустить его.
Linux Ссылка на заголовок
Установите пакет qt development tools, который имеет различные имена в зависимости от вашего дистрибутива.
sudo apt install qttools5-dev-tools # QT5, Ubuntu/Mint
sudo apt install qttools6-dev-tools # QT6, Ubuntu/Mint
sudo dnf install qt5-qttools-libs-designer # QT5, Fedora
sudo dnf install qt5-qttools-libs-designer # QT6, Fedora
sudo pacman -S qt5-tools #QT5, Arch
sudo pacman -S qt6-tools #QT6, Arch
nix-shell -p libsForQt5.qt5.qttools # QT5, Nix
nix-shell -p qt6.qttools # QT6, Nix
После этого запустите designer
в командной строке, открыв Qt Designer, или напишите .desktop файл для быстрого запуска из интерфейса.
Интерфейс QT Designer Ссылка на заголовок
Это находится главное окно QT дизайнера. Для простоты я выделила важные регионы на скриншоте.
- Главная Рабочая Зона
- Инспектор Объектов
- Редактор Свойств
- Редактор Сигналов (и две других вкладки)
- Список Виджетов
- Лента с кнопками
- Лента меню
Создание интерфейса Ссылка на заголовок
Итак, мы создадим простой интерфейс для текстового редактора (“блокнота”). Для этого нам нужно три вида виджетов:
Интерфейс перетаскиванием Ссылка на заголовок
Одна из вещей, которая совершенно неправильно объяснена во многих похожих туториалах, это то, как они просят вас вручную перетащить виджеты из окна виджетов (5) в ваш интерфейс (1) и расположить их так, как вы хотите. Если мы попробуем сделать это, то все получится, но…
Как видите, это не очень хорошо масштабируется…
Использование макетов Ссылка на заголовок
Поэтому вместо этого мы используем макеты (раскладки, разметки, layouts), которые представляют собой контейнеры, автоматически упорядочивающие и изменяющие размеры виджетов на основе простых правил.
Самые основные из них - горизонтальный и вертикальный макеты:
Мы будем использовать сетчатый макет:
Поэтому мы размещаем наши виджеты на сетке так, как нам нужно…
И видим, что пока это выглядит не совсем как то что нам надо. Чтобы исправить это, удерживаем левую кнопку мыши по бокам виджета редактирования текста и несколько раз изменяем его размер, чтобы он занял всю ширину нашего макета.
Также вы можете добавить виджет горизонтальный разделитель
для разделения кнопок и строки поиска.
Затем мы нажимаем правую кнопку вне макета и выбираем Lay out
в контекстном меню, выбирая любой из макетов, упомянутых выше, чтобы преобразовать само окно в макет.
Изменение свойств виджетов Ссылка на заголовок
Изменить текст на кнопке довольно просто: дважды щелкните на ней левой кнопкой мыши и введите свой текст.
Но нам нужно гораздо больше изменений, поэтому мы выберем виджеты либо напрямую выделяя их, либо с помощью инспектора объектов (2), затем перейдем к свойствам объекта (3), чтобы отредактировать нужные нам.
Имя | ID | Описание |
---|---|---|
Object Name | objectName | Идентификатор объекта, используемый в коде, поэтому убедитесь, что его легко понять |
Text | text | Текст на кнопках и других объектах. Для редактирования текста и редактирования строк он будет помещать уже существующий “настоящий” текст, а не текст-заполнитель, который вам обычно нужен. |
Placeholder Text | placeholderText | Серые подсказки внутри виджетов редактирования строки и текста |
Tooltip | toolTip | Текст, который отображается при наведении курсора на кнопку, напишите здесь более подробное описание |
Результат будет выглядеть следующим образом:
Вы также должны добавить специальное название и описание к добавленным виджетам. Это минимум того, что вы можете сделать, чтобы ваше программное обеспечение стало доступным для большего числа пользователей с ограниченными возможностями.
Специальное имя | acessibleName | Имя объекта, которое программа чтения с экрана читает для пользователей с ослабленным зрением |
Специальное описание | acessibleDescription | Что-то вроде подсказки для пользователей программ для чтения с экрана |
Tab order Ссылка на заголовок
Правильный порядок виджетов, с другой стороны, позволяет использовать кнопку Tab
для фокусировки на следующем (или предыдущем, при использовании Shift+Tab
) интерактивном виджете, используя только клавиатуру, что также полезно для пользователей программ чтения с экрана и других людей, которым необходимо перемещаться по вашему приложению с клавиатуры.
Выберите режим Редактировать Tab Order
в Ленте кнопок (6) и проверьте, пронумерованы ли кнопки в порядке слева направо, сверху вниз, если нет, нажмите на все из них в этом порядке.
Для этой же цели можно использовать список порядка вкладок.
Настройка действий Ссылка на заголовок
Далее мы добавим действия, которые выступают и как пункты в строке меню, и как действия, к которым можно добавить горячие клавиши.
- Дважды нажмите на
Type here
в пустой строке меню вашего окна и введите название категории. - Нажмите еще раз и выберите
Type here
в выпадающем меню, на этот раз введя название действия. Здесь же можно добавить разделители групп действий. - Выберите новое действие и отредактируйте запись
shortcut
в редакторе свойств, добавив горячие клавиши.
Для нашего простого редактора я рекомендую следующий список горячих клавиш и действий:
Категория > Имя | Шорткат |
---|---|
Файл > Новый | Ctrl+N |
Файл > Открыть… | Ctrl+O |
Файл > Сохранить | Ctrl+S |
Файл > Сохранить как… | Ctrl+Shift+S |
Файл > Выйти | Ctrl+Q |
Редактирование > Поиск | Ctrl+F |
Сигналы Ссылка на заголовок
Наконец, мы должны добавить сигналы. Сигналы позволяют нам соединять различные окна и/или действия, чтобы изменение состояния одного из них влияло на другое. В нашем случае мы хотим, чтобы наши кнопки были связаны с соответствующими действиями, а действие Поиск
фокусировало нашу панель поиска.
Мы могли бы использовать кнопку из панели кнопок (6) для входа в режим редактирования сигналов, но она не позволяет подключать действия, поэтому мы будем использовать Редактор сигналов (4) для добавления нового сигнала и выбора:
- Кнопка по её objectName в качестве Sender
clicked()
в качестве Сигнала- Действие по objectName в качестве получателя
trigger()
как Slot
В свою очередь, для действия Поиск
нам нужно использовать triggered()
и setFocus()
Проделайте это для всех кнопок, и мы практически закончили работу с QT дизайнером, осталось только сохранить проект как .ui файл и поместить его в папку проекта.
Подключение интерфейса к коду PyQT5 Ссылка на заголовок
После того как мы закончим со всем этим, нам все равно нужно будет внедрить этот интерфейс в наше приложение. В качестве примера мы будем использовать PyQT5, библиотеку языка Python для QT.
Загрузка интерфейса из кода Ссылка на заголовок
Чтобы загрузить интерфейс, у нас есть два разных способа. Один из них - преобразовать ui-файл, который мы можем сохранить из QT Designer, в python-код, используя инструмент командной строки uic
или сгенерировав его из самого QT Designer.
pyuic5 interface_filename.ui > interface_filename.py
from PyQt5.QtWidgets import QMainWindow, QApplication
from interface_filename import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__() # инициализация QMainWindow
# Загрузка и применение интерфейса из py файла
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
Другой способ - использовать uic
в качестве библиотеки и загружать UI-файл напрямую, конвертируя его во время выполнения. Второй способ добавляет немного нагрузки на компьютер в приложение и требует поставки ui файла вместе с ним, но позволяет быстро протестировать изменения в .ui файле, просто перезапустив код.
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import uic
class MainWindow(QMainWindow):
def __init__(self):
super().__init__() # инициализация QMainWindow
# Загрузка и применение интерфейса из ui файла
uic.loadUi("interface_filename.ui",self)
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
Между ними есть два различия, которые влияют на наш проект:
- В первом методе объекты называются как
self.ui.objectName
, поскольку мы импортировали их как объект с именемui
, в то время как во втором методе мы используем простоself.objectName
. - Если вы используете второй метод, он странно игнорирует настройки отступов центрального виджета, из-за чего у него нет пространства между кнопками и краями окна, поэтому нам нужно, чтобы у нашего макета сетки, добавленного вручную, был отступ, что мы сделаем используя редактор свойств (3) (Вы также можете установить свойство margin на 0 в центральном виджете, чтобы не было несоответствия между способами)
Подключение к функциям Ссылка на заголовок
После этого нам нужно добавить несколько функций, которые заставят наш интерфейс работать. Здесь я не буду подробно рассказывать о том, как работают эти функции, так как это в основном видео по qt designer, поэтому мы сосредоточимся на том, как подключить их к нашим виджетам.
QT Designer сделал за нас часть работы, позволив нам просто вызывать виджеты из кода по их именам (в случае Python, self.objectName
для метода uic как библиотеки, или self.ui.objectName
, если мы использовали первый метод), поэтому мы добавим код, который свяжет сигналы действия triggered
с функциями в __init__
нашего объекта MainWindow
.
self.ui.actionNew_file.triggered.connect(self.create_new_file)
# ИЛИ
self.actionNew_file.triggered.connect(self.create_new_file)
Для кнопок мы бы использовали clicked
вместо triggered
, но мы уже связали их с сигналами, так что в этом нет необходимости.
Исключением является поле поиска, мы используем returnPressed
для запуска функции поиска.
self.ui.searchBar.returnPressed.connect(self.search_text)
# ИЛИ
self.searchBar.returnPressed.connect(self.search_text)
Conclusion Ссылка на заголовок
Полные файлы проекта вы можете найти здесь - https://codeberg.org/system-maid/cute-writer.
Возможно, я сделаю продолжение для более сложных интерфейсов или кода PyQT5, а пока прощайте, надеюсь, мы еще увидимся.