alt
Логотип Qt

В этой статье я попытаюсь рассказать вам о прекрасной библиотеки PySide (которая является биндингом Qt) на языке Python.

Так же существует популярный неофициальный аналог - PyQt. Я не рекомендую его использовать по многим причинам, из которых например не подходящая лицензия для коммерческого использования (GPL, в отличии от LGPL), а так же отсутствие дополнительных приложений и пакетов.

Мы будем использовать самую новую версию PySide6 (по состоянию на 2025 год) и Python с официального сайта

Так же существуют устаревшие версии PySide:

  • PySide1 (Qt 4)

  • PySide2 (Qt 5)

  • PySide6 (Qt 6) актуальная версия

Нам требуется:

  • Python (https://www.python.org/downloads/)

  • Удобная IDE/редактор кода (Visual Studio Code или PyCharm)

  • Сам PySide6 - «pip install PySide6»

  • Знания ООП (хотябы минимальные)

Документация

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

Приступим!

После установки PySide6 можно приступать к изучению.

Для начала хотелось бы рассказать что такое Qt в целом.

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

Сам оригинальный Qt создан для C++ а PySide6 испольняет роль "биндинга" (привязки) то есть мы пишем на Python а сама библиотека написана на С++ (внутри используется shiboken6, который помогает использовать C++ код в Python)

alt
Логотип Qt for Python

С помощью Qt можно создать много разных приложений.
С помощью данного фреймворка написаны такие популярные приложения:

  • Telegram (!)

  • qBittorrent

  • VLC Media Player

  • OBS Studio

  • VirtualBox

  • и много других

* Стоит учитывать что они написаны именно на оригинальном C++/Qt а не Python/Qt

Hello, World!

Ну что же, напишем первое приложение.

Совет: Используйте «pyside6-project» для создания нового проекта PySide6 с готовой системой каталогов

В данном случае мы создадим проект вручную.
Создаю папку testapp в ней main.py

Импортируем библиотеку

from PySide6.QtWidgets import QApplication, QLabel

app = QApplication()

label = QLabel("Hello, World!")
label.show()

app.exec()

Совет: в некоторых туториалах могут использоваться старые способы. Например sys.exit(app.exec()), QApplication(sys.argv), и т.д. В новых версиях Qt данные телодвижения не требуются, всё делается автоматически.

Запускаем, получаем окно с надписью Hello, World!
В данном случае мы создаём экземпляр приложения (QApplication), добавляем к нему виджет "label" (текст), показываем этот виджет и запускаем приложение.
Позже в данной статье я расскажу о QMainWindow, QWidget и centralWidget.

Qt Designer

pyside6-designer

Qt Designer — это визуальный инструмент для разработки пользовательских интерфейсов (GUI) в рамках фреймворка Qt. Он позволяет создавать окна, формы и виджеты с помощью drag-and-drop, без необходимости писать код вручную.

Данное приложение очень помогает при разработке приложений, позволяет настраивать элементы окна и много чего, чего даже я не знаю

Совет: вы можете изменить тему приложения (не только белую и черную, а и другие) используя параметр -style (пример: pyside6-designer -style WindowsVista). Подробнее про стили мы поговорим позже.

Я рекомендую использовать встроенное в приложение в PySide6 приложение используя команду pyside6-designer, это ярлык. Настоящее приложение находиться в вашей папке site-packages/PySide6/designer.exe

Вы можете скачать его используя полный пакет Qt, в котором так же есть IDE для разработки Qt приложний с поддержкой Python - Qt Creator. Если честно, мне не понравилась данная идея. Пакет PySide6 имеет всё что нужно.

Ещё вариант скачать скомпилированный автономный вариант - https://build-system.fman.io/qt-designer-download

QMainWindow (главное окно)

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

Совет: в примере приложение Hello, World! мы не создавали окно приложения и просто показывали виджет. Чтобы показывать несколько виджетов нужно показывать каждый виджет отдельно (не практично, не используется) или создать окно, в которое будут помещаться ваши виджеты (лучший вариант)

QWidget позволяет создавать свои кастомные виджеты, с другими виджетами, настройками и т.д.

QCentralWidget наследуется от QWidget и является главным виджетом окна. Для него используется Layout (QLayout или просто компоновщик) который позволяет правильно распологать виджеты и даёт возможность их перемещать при изменении размера окна.

Совет: если вы выбирите QWidget как главное окно вашего приложения, то вы не сможете изменить название окна, иконку, а также другие параметры. Используйте QMainWindow

Так же существует menuBar. Как все привыкли - Файл, Правка, Свойства. Контекстное меню вверху окна.
Внизу - statusBar где может помещаться разная информация.
toolBar - панель инструментов, где можно быстро что-то вызвать или использовать.

DockWidget — это виджет который используется для создания "плавающих" панелей вокруг главного окна. Такие панели можно перетаскивать, закреплять сбоку, скрывать и снова показывать.

Создаём первое приложение с помощью Qt Designer

Заходим, выбираем стандартные параметры (MainWindow), нажимаем «Создать». Попадаем в главное окно редактора. Слева встречает окно с виджетами, справа управлениями свойствами. Вы можете перемещать эти панели как хотите, а так же убирать их.

Для примера давайте создадим приложение которое позволяет генерировать случайные числа

Перемещаем QLayout например на центр, а QPushButton вниз. Справа находим редактор объектов и для centralWidget выбираем layout используя панель слева вверху (панель инструментов). Можно сделать горизонтально, вертикально и так далее.

Форма -> Предпросмотр. Видим как приложение выглядит. Сохраняем .ui в папку проекта.

.ui файлы, динамическая загрузка

После сохранения интерфейса мы сохраняем файл .ui
По сути это XML файл с настройками интерфейса который принимает Qt. Для простых примеров его можно динамически загружать, но в больших это не рекомендуется. Его нужно переводить в Python код. Для этого использует утилита pyside6-uic

pyside6-uic design.ui -o design.py

Появится design.py файл с готовым классом приложения и его настройками.
В главном файле импортируем его:

from design import Ui_MainWindow

После этого мы можем запустить интерфейс. Для теста:

from PySide6.QtWidgets import QApplication, QMainWindow
from design import Ui_MainWindow

app = QApplication()
window = QMainWindow()

ui = Ui_MainWindow()
ui.setupUi(window)

window.show()
app.exec()

Запускаем. Проверяем. Видим интерфейс.

Сигналы и слоты

Допустим, есть кнопка. Когда ты на неё жмёшь, она посылает сигнал.
А если ты сказал: "Когда кнопка нажата — вызови функцию say_hi()", то say_hi() — это слот, который сработает в ответ на сигнал.

Сами слоты мы должны писать в коде, по сути это просто функции.
Обозначить слоты можно в Designer-е, но не обязательно.

Приложение

Прошлый пример только для тестирования что всё работает. Для нормального приложения мы должны создать класс:

from PySide6.QtWidgets import QApplication, QMainWindow
from design import Ui_MainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

def main():
    app = QApplication()
    window = MainWindow()
    window.show()
    app.exec()

if __name__ == "__main__":
    main()

Видим - всё работает. Создаём сигналы и слоты. Спросите, как? Всё просто, создаём функции в классе MainWindow.

Например:

import random 

def generate_number(self):
        number = random.randint(1, 100)
        self.ui.label.setText(number)

Теперь нужно создать сигнал. Если проще, "подключить" виджет к слоту.

self.ui.pushButton.clicked.connect(self.generate_number)

Готово. Мы написали код. Полное приложение:

import random
from PySide6.QtWidgets import QApplication, QMainWindow
from design import Ui_MainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.pushButton.clicked.connect(self.generate_number)
    def generate_number(self):
        number = random.randint(1, 100)
        self.ui.label.setText(number)

def main():
    app = QApplication()
    window = MainWindow()
    window.show()
    app.exec()

if __name__ == "__main__":
    main()

Теперь можем запускать проект. Всё работает!

Изменение параметров окна

Что делать если вы хотите изменить иконку, размер, название окна и ещё много чего? Расскажу самое главное.

Иконка:

from PySide6.QtGui import QIcon
self.setWindowIcon(QIcon('path/to/icon.png'))

* Так же мы можем изменить иконку всего приложения, в данном случае если иконка для окна не задана то будет иконка приложения по умолчанию

Размер:

self.resize(800, 600)

Название:

self.setWindowTitle("My Window")

Больше параметров вы найдёте в официальной документации Qt и Qt for Python.
Эти параметры можно использовать двумя способами. Первый способ вставить в класс окна (MainWindow). Второй способ заменить self на window и вставить в функцию main()

Стили окна

app.setStyle("Fusion")

Мы можем изменять стиль приложения, например Windows (старый стиль для совместимости), WindowsVista (Legacy стиль Windows Aero), современный Fusion и много чего. Некоторые стили зависят от платформы.

Больше информации про стили вы найдёте в официальной документации - https://doc.qt.io/qt-6/qstyle.html#details

Итог

Мы создали приложение, написали код, настроили стиль. Все работает.

Мы можем создать новые окна, добавить другие слоты и сигналы и много чего. Что бы я ещё сделал? Наверное если приложение полезное, его можно упаковать в .exe файл а потом в установщик. Например используя связку pyinstaller + Inno Setup. Но это в следующий раз...

Комментарии (9)


  1. Andrey4ik Автор
    13.05.2025 16:06

    Это моя первая статья на хабре и в целом, поэтому не судите строго :)


  1. Rusrst
    13.05.2025 16:06

    А что там с qml? Или только widgets?


    1. Andrey4ik Автор
      13.05.2025 16:06

      Собираюсь создать 2 и 3 часть статьи про другие темы включая qml. Но я сам не разбирал ещё это. Всё будет только если статья получит хорошие комментарии и у меня будет мотивация. В ином случае не знаю. Как тебе? Мне нужны отзывы как я пишу :/ просто захотелось в жизни)


      1. Rusrst
        13.05.2025 16:06

        Я почитал, негативных эмоций не было :)

        Но я на python не пишу.


        1. Andrey4ik Автор
          13.05.2025 16:06

          Спасибо за фидбек


  1. Lalso
    13.05.2025 16:06

    "Так же существует популярный неофициальный аналог - PyQt. Я не рекомендую его использовать по многим причинам, из которых например не подходящая лицензия для коммерческого использования (GPL, в отличии от LGPL), а так же отсутствие дополнительных приложений и пакетов."

    А какой???


    1. Andrey4ik Автор
      13.05.2025 16:06

      Там же написано - PyQt


  1. NikiRiki
    13.05.2025 16:06

    Интересная тема. Зачастую намного удобнее написать "классическое" приложение, которое запускается без очередной вкладки в веб браузере.


    1. Andrey4ik Автор
      13.05.2025 16:06

      Это очень полезно вообще. Часто используется