Library Guide

PyQt & PySide

Industrial-strength Qt bindings for large, professional desktop applications.

Professional Feature-rich Licensing care

What Is Qt for Python?

Qt is a vast, mature C++ application framework used in commercial software worldwide β€” from video editors and CAD tools to embedded displays. Python accesses Qt through two binding families: PyQt (Riverbank Computing, GPL or commercial license) and PySide (official Qt Company binding, LGPL). Their APIs are nearly identical; most PyQt6 code runs on PySide6 with import renames.

Qt is far more than widgets: it includes networking, SQL, multimedia, WebEngine, charts, 3D, Bluetooth, and the declarative QML language for fluid, animated UIs.

PyQt vs PySide?

Choose PySide6 for permissive LGPL licensing (safer for proprietary apps). Choose PyQt6 if you prefer Riverbank's ecosystem and accept GPL or buy a commercial license. Functionally they are interchangeable for most projects.

Architecture & Core Concepts

  • QApplication β€” single app object; owns the event loop. Call app.exec().
  • QWidget hierarchy β€” windows, dialogs, and controls form a parent-child tree.
  • Layouts β€” QVBoxLayout, QHBoxLayout, QGridLayout, QFormLayout replace manual positioning.
  • Signals & slots β€” type-safe event system: button.clicked.connect(handler).
  • Model/View β€” QTableView, QTreeView bind to data models for large datasets.
  • Qt Designer β€” drag-and-drop .ui files loaded with QUiLoader or converted to Python.

Major module groups

ModuleContains
QtWidgetsButtons, labels, tables, dialogs, main windows
QtCoreSignals, timers, threads, file I/O, settings
QtGuiFonts, colors, icons, images, clipboard
QtChartsLine, bar, pie charts (add-on module)
QtMultimediaAudio/video playback and capture
QtWebEngineWidgetsEmbedded Chromium browser

Installation

shell
pip install PySide6          # recommended for most projects
pip install PySide6-Addons   # charts, web engine, etc.

# Alternative:
pip install PyQt6

# Optional: Qt Designer is included; run:
pyside6-designer

Example 1 β€” Counter with signals

python Β· PySide6
import sys
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel

app = QApplication(sys.argv)
win = QWidget()
win.setWindowTitle("PySide6 demo")

layout = QVBoxLayout(win)
label  = QLabel("Counter: 0")
button = QPushButton("Increment")
layout.addWidget(label)
layout.addWidget(button)

count = {"n": 0}
def bump():
    count["n"] += 1
    label.setText(f"Counter: {count['n']}")

button.clicked.connect(bump)
win.show()
sys.exit(app.exec())

Example 2 β€” Main window with menu bar

python Β· PySide6
import sys
from PySide6.QtWidgets import (
    QApplication, QMainWindow, QTextEdit, QMenuBar
)
from PySide6.QtGui import QAction

class Editor(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Simple Editor")
        self.editor = QTextEdit()
        self.setCentralWidget(self.editor)

        bar = self.menuBar()
        file_menu = bar.addMenu("File")
        quit_action = QAction("Quit", self)
        quit_action.triggered.connect(self.close)
        file_menu.addAction(quit_action)

app = QApplication(sys.argv)
win = Editor()
win.resize(600, 400)
win.show()
sys.exit(app.exec())

Example 3 β€” Thread-safe background work

Never block the GUI thread. Use QThread and signals to update the UI when work finishes.

python Β· PySide6
from PySide6.QtCore import QThread, Signal
from PySide6.QtWidgets import QPushButton, QLabel, QVBoxLayout, QWidget
import time

class Worker(QThread):
    finished = Signal(str)
    def run(self):
        time.sleep(2)
        self.finished.emit("Done!")

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.label = QLabel("Idle")
        btn = QPushButton("Start")
        btn.clicked.connect(self.start)
        QVBoxLayout(self).addWidget(self.label)
        self.layout().addWidget(btn)
    def start(self):
        self.label.setText("Working…")
        self.worker = Worker()
        self.worker.finished.connect(self.label.setText)
        self.worker.start()

Practical advice

  • Structure large apps with separate files for views, models, and controllers.
  • Use QSettings to persist window size, recent files, and preferences.
  • Load .ui files from Qt Designer for faster iteration on layout.
  • For a multi-framework visual builder (Tk, CTk, Kivy, Flet), see MD Python Designer.
  • Prefer QFormLayout for aligned label-field pairs.
  • Bundle with PyInstaller or cx_Freeze; expect 50–150 MB due to Qt libraries.
  • For async code, consider qasync to integrate asyncio with the Qt event loop.

Real-world use cases

  • Professional desktop software (editors, IDEs, scientific tools)
  • Cross-platform commercial products with rich UI requirements
  • Data visualization dashboards with Qt Charts
  • Embedded HMIs and industrial control panels
  • Apps needing embedded web content via Qt WebEngine

βœ“ Strengths

  • Huge, professional widget library
  • Signals/slots; great for large architectures
  • Qt Designer drag-and-drop UI builder
  • Excellent docs, charts, multimedia, QML
  • Mature, battle-tested in industry

βœ— Weaknesses

  • Steeper learning curve
  • Licensing complexity (esp. PyQt/GPL)
  • Larger install & bundle size
  • Mobile support limited compared to Flutter/Kivy
Use it when

Building a serious, complex, long-lived desktop application that needs rich widgets, maintainable structure, and professional polish. Avoid for tiny scripts or mobile-first projects.