Введение
Статья 499 разобрала выбор между библиотеками — далее в этом цикле будем использовать PySide6 как основную, официальную обёртку. В этой статье разберём установку и минимальное, но полное первое приложение, повторяющее структуру самого первого примера основного, C++-ориентированного цикла статей, но на Python.
Концепция
PySide6 устанавливается стандартным менеджером пакетов Python (pip), без необходимости отдельной установки Qt SDK или настройки сложной системы сборки (CMake/qmake), требуемой для C++ Qt-проектов — это одно из практических преимуществ Python-разработки с Qt, существенно снижающее порог входа для быстрого старта. Минимальное приложение требует ровно тех же концептуальных элементов, что и C++-версия из основного цикла статей — единственный экземпляр QApplication, управляющий событийным циклом приложения, и хотя бы один видимый виджет (QWidget или производный от него класс), и запуск событийного цикла через app.exec().
Пример кода: Установка и первое приложение на PySide6
# Установка PySide6 через pip — единственная команда, без отдельной установки Qt SDK
pip install PySide6
# Минимальное полное приложение — прямой аналог C++ "Hello World" из основного цикла статей
import sys
from PySide6.QtWidgets import QApplication, QPushButton
app = QApplication(sys.argv) # sys.argv передаёт аргументы командной строки, как и в C++ версии
button = QPushButton("Нажми меня")
button.resize(200, 50)
button.show()
sys.exit(app.exec()) # exec() без последней буквы "_" в Python-версии (в C++ это exec())
# Более структурированный пример с собственным классом окна — типичный для реальных приложений паттерн
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Моё первое приложение PySide6")
self.resize(400, 300)
central_widget = QWidget()
layout = QVBoxLayout(central_widget)
button = QPushButton("Нажми меня")
button.clicked.connect(self.on_button_clicked) # статья 501 — подробный разбор сигналов/слотов
layout.addWidget(button)
self.setCentralWidget(central_widget)
def on_button_clicked(self):
print("Кнопка нажата!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
Пояснения к кода
Минимальный пример показывает, что структура Python-приложения на PySide6 концептуально идентична C++-версии из основного цикла статей (QApplication → создание виджета → show() → exec()), с естественными синтаксическими отличиями, диктуемыми самим языком Python (явный import, sys.argv/sys.exit() вместо аргументов main() и его возвращаемого значения). Более структурированный пример с собственным классом MainWindow, наследующим QMainWindow, показывает идиоматичный для реальных приложений паттерн — аналогично C++ Qt-коду (основной цикл статей), Python-код также обычно организуется через собственные классы, наследующие соответствующие базовые классы Qt, а не через единственную, плоскую последовательность вызовов на верхнем уровне модуля. Конструкция if __name__ == "__main__": — стандартная, идиоматичная для Python практика, гарантирующая, что код запуска приложения выполняется только при непосредственном запуске этого файла, а не при его импорте как модуля в другом коде.
Подводные камни
- Забытое сохранение ссылки на созданный виджет в переменной с достаточно долгим временем жизни — в отличие от C++ (где явное управление памятью через
new/родительские отношения Qt-объектов более привычно), в Python сборщик мусора может удалить объект виджета, если на него не осталось ни одной активной ссылки, даже если этот виджет технически отображён на экране — это может привести к неожиданному, необъяснимому исчезновению окна, и для надёжности стоит либо сохранять явную ссылку на виджет (какwindow = MainWindow()в примере), либо явно задавать родителя через стандартный механизм Qt-объектов. - Использование устаревшего, не актуального для PySide6 синтаксиса
app.exec_()с подчёркиванием в конце — этот синтаксис исторически использовался в Python 2 для избежания конфликта с зарезервированным словомexec, но в современных версиях PySide6 (и для Python 3, гдеexecне является зарезервированным словом для конструкторов классов в этом контексте) рекомендуется использоватьapp.exec()без подчёркивания, хотяexec_()может оставаться доступным как устаревший, но рабочий alias для совместимости. - Создание нескольких экземпляров
QApplicationв рамках одного процесса — аналогично C++ версии Qt, в рамках одного процесса может существовать только один экземплярQApplication, и попытка создать второй приводит к ошибке или неопределённому поведению; для тестов (статья 509) или повторного использования кода это требует аккуратного, явного управления единственным экземпляром приложения. - Игнорирование важности виртуальных окружений Python (venv/conda) при установке PySide6, что может привести к конфликтам версий зависимостей между разными Python-проектами на одной машине разработчика — установка PySide6 непосредственно в системный, общий для всех проектов Python без изоляции через виртуальное окружение рискует созданием конфликтов при необходимости использовать разные версии PySide6 (или несовместимые версии других пакетов) для разных проектов на той же машине.