Разработка десктопных приложений Python с помощью Qt

Раздел: Графические интерфейсы -> Графические интерфейсы (Qt)

Создание интерфейсов на Python с использованием Qt

Как использовать Qt Designer для быстрой разработки интерфейса?

Этот подход позволяет визуально скомпоновать элементы интерфейса и затем загрузить макет в код. Для начала установите PyQt6: pip install PyQt6. Запустите Qt Designer (поставляется с PyQt6) через командную строку: pyqt6-tools designer. Создайте главное окно, добавьте кнопку и текстовое поле. Сохраните файл как main.ui.

import sys
from PyQt6 import uic
from PyQt6.QtWidgets import QApplication

app = QApplication(sys.argv)
window = uic.loadUi("main.ui")
window.show()
sys.exit(app.exec())

Python qt (python и qt)

После загрузки все сигналы и слоты доступны. Для подключения обработчика используйте window.pushButton.clicked.connect(handler).

Типичные ошибки:

  • Файл .ui не найден - укажите полный путь или используйте os.path.
  • Версия PyQt5 vs PyQt6 - утилита uic может отличаться.
  • Имена объектов в Designer должны соответствовать тем, что используются в коде.

Как создать простой интерфейс с помощью кода?

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

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel, QWidget

def on_click():
    label.setText("Нажата!")

app = QApplication(sys.argv)
window = QMainWindow()
central = QWidget()
layout = QVBoxLayout()
label = QLabel("Текст")
button = QPushButton("Кнопка")
button.clicked.connect(on_click)
layout.addWidget(label)
layout.addWidget(button)
central.setLayout(layout)
window.setCentralWidget(central)
window.show()
sys.exit(app.exec())

Метод даёт гибкость в расположении, но требует больше кода.

Ошибки:

  • Забыли вызвать setLayout - виджеты не отобразятся.
  • Неправильное использование setCentralWidget для QMainWindow.

Как применить QML для создания современного интерфейса?

QML позволяет описывать интерфейс декларативно с анимациями. Установите модуль PyQt6.QtQml:

import sys
from PyQt6.QtGui import QGuiApplication
from PyQt6.QtQml import QQmlApplicationEngine

app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load("main.qml")
sys.exit(app.exec())

Файл QML может содержать императивный JavaScript. Этот подход хорошо подходит для сложных визуализаций.

Проблемы:

  • Требуется знание QML и JavaScript.
  • Некоторые возможности C++ недоступны без регистрации типов.

Как добавить диаграмму в приложение?

Модуль Qt Charts предоставляет типы графиков. Установите PyQt6.QtCharts (доступен в PyQt6). Пример с линейной диаграммой:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt6.QtCharts import QChart, QChartView, QLineSeries

app = QApplication(sys.argv)
window = QMainWindow()
central = QWidget()
layout = QVBoxLayout()
series = QLineSeries()
series.append(0, 0)
series.append(1, 2)
series.append(2, 5)
chart = QChart()
chart.addSeries(series)
chart.createDefaultAxes()
chartView = QChartView(chart)
layout.addWidget(chartView)
central.setLayout(layout)
window.setCentralWidget(central)
window.show()
sys.exit(app.exec())

Подобный код добавляет простую диаграмму.

Ошибки:

  • Модуль может отсутствовать в некоторых дистрибутивах - проверьте установку.
  • Необходимо вызывать createDefaultAxes после добавления серий.

Как выполнить длительную операцию без зависания интерфейса?

Для неблокирующих вычислений используйте QThread. Пример:

import sys, time
from PyQt6.QtCore import QThread, pyqtSignal
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QLabel

class Worker(QThread):
    finished = pyqtSignal(str)
    def run(self):
        time.sleep(5)  # имитация работы
        self.finished.emit("Завершено")

app = QApplication(sys.argv)
window = QMainWindow()
central = QWidget()
layout = QVBoxLayout()
label = QLabel("Ожидание")
button = QPushButton("Старт")
def start_worker():
    worker = Worker()
    worker.finished.connect(label.setText)
    worker.start()
button.clicked.connect(start_worker)
layout.addWidget(label)
layout.addWidget(button)
central.setLayout(layout)
window.setCentralWidget(central)
window.show()
sys.exit(app.exec())

Данный подход сохраняет отзывчивость интерфейса.

Проблемы:

  • Необходимо правильно управлять временем жизни потока, чтобы избежать утечек.
  • Сигналы должны быть объявлены как pyqtSignal.

Цели и случаи использования:

  • Основное решение с Designer: быстрое прототипирование, стандартные формы.
  • Ручное создание: кастомизация, динамические интерфейсы.
  • QML: анимации, мобильные приложения.
  • Qt Charts: аналитические панели, дашборды.
  • QThread: фоновые задачи, работа с сетью.

Расширенные примеры работы с Qt

Далее представлены более сложные сценарии, расширяющие стандартные возможности.

Кастомный виджет с рисованием

Переопределение метода paintEvent позволяет рисовать произвольные фигуры. Пример виджета, рисующего круг:

Пример
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt6.QtGui import QPainter, QColor, QBrush
from PyQt6.QtCore import QRect

class CircleWidget(QWidget):
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setBrush(QBrush(QColor(0, 128, 255)))
        painter.drawEllipse(QRect(10, 10, 100, 100))

app = QApplication(sys.argv)
window = QMainWindow()
window.setCentralWidget(CircleWidget())
window.resize(200, 200)
window.show()
sys.exit(app.exec())

Результат: окно с синим кругом.

Использование модели для QTableView

QAbstractTableModel позволяет отображать данные в таблице. Пример с простым списком:

Пример
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QTableView, QWidget, QVBoxLayout
from PyQt6.QtCore import QAbstractTableModel, QModelIndex, Qt

class MyModel(QAbstractTableModel):
    def rowCount(self, parent=QModelIndex()):
        return 3
    def columnCount(self, parent=QModelIndex()):
        return 2
    def data(self, index, role=Qt.ItemDataRole.DisplayRole):
        if role == Qt.ItemDataRole.DisplayRole:
            return f"({index.row()},{index.column()})"
        return None

app = QApplication(sys.argv)
window = QMainWindow()
central = QWidget()
layout = QVBoxLayout()
table = QTableView()
table.setModel(MyModel())
layout.addWidget(table)
central.setLayout(layout)
window.setCentralWidget(central)
window.show()
sys.exit(app.exec())

Таблица показывает ячейки с координатами.

Анимация перемещения виджета

QPropertyAnimation позволяет плавно менять свойства. Пример анимации кнопки:

Пример
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtCore import QPropertyAnimation, QPoint

app = QApplication(sys.argv)
window = QMainWindow()
central = QWidget()
layout = QVBoxLayout()
btn = QPushButton("Двигайся")
layout.addWidget(btn)
central.setLayout(layout)
window.setCentralWidget(central)
window.show()

anim = QPropertyAnimation(btn, b"pos")
anim.setEndValue(QPoint(200, 200))
anim.setDuration(2000)
anim.start()

sys.exit(app.exec())

Кнопка перемещается в указанную точку за 2 секунды.

Отображение веб-страницы через QWebEngineView

Для встраивания браузера используется модуль PyQt6.QtWebEngineWidgets:

Пример
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView

app = QApplication(sys.argv)
window = QMainWindow()
central = QWidget()
layout = QVBoxLayout()
web = QWebEngineView()
web.load("https://www.python.org")
layout.addWidget(web)
central.setLayout(layout)
window.setCentralWidget(central)
window.resize(800, 600)
window.show()
sys.exit(app.exec())

Приложение отображает сайт Python.org.

Python и Qt - comments

En
Python qt (python)