Skillversitas

Installation and Licensing

Installing PyQt means choosing the binding line (the PyQt5 for Qt 5, the PyQt6 for Qt 6), installing it and its Qt runtime through the package manager or pip, and understanding the licensing that governs the use - the PyQt5/PyQt6 are available under the GPL and under the commercial Qt license, with the choice depending on the app's own distribution. The verification is the import that reports the Qt and the PyQt versions, and the platform note is the one that matters on each OS (the macOS framework build, the Windows binary, the Linux system Qt). This chapter covers the installation for the three lines (the pip, the distro package, the source), the version verification, the platform specifics, and the licensing decision.

Installing the Binding

# the pip install - the standard path (the wheel bundles the
# Qt libraries, no system Qt needed on the common platforms):
pip install PyQt5        # the Qt 5 line (the stable, the
                         # broadest compatibility)
pip install PyQt6        # the Qt 6 line (the current)

# the companion packages, installed with the base on the
# common platforms (the optional feature modules):
pip install PyQtWebEngine   # the QtWebEngine (the web content)

# the distro packages (the system Qt, the distro's binding):
sudo apt install python3-pyqt5        # Debian / Ubuntu
sudo dnf install python3-qt5          # Fedora / RHEL

# the PyQt5-tools (the pyuic, the pyrcc, the design tools):
pip install PyQt5-tools
# (the PyQt6 equivalent: the pyuic6, the pyrcc6)

# the check: the pip shows the installed line
pip show PyQt5 | head -3

The pip install is the standard path: pip install PyQt5 (the Qt 5 line, the stable with the broadest compatibility) or pip install PyQt6 (the Qt 6 line, the current), and the wheel bundles the Qt libraries, so no system Qt is needed on the common platforms. The distro packages (python3-pyqt5 on Debian/Ubuntu, the equivalent on Fedora) install the binding against the system Qt, which is the path on the systems that manage their Qt through the distro. The PyQt5-tools (the pyuic for the UI compilation, the pyrcc for the resource compilation - the later chapters) is the companion package for the design tools. The choice between the pip and the distro is the one the deployment makes: the pip is the self-contained (the bundled Qt, the version the app pinned), the distro is the system-managed (the Qt the distro ships, the version the distro controls). The verification is the import in the next section, and the platform note follows.

The Version Check

import sys
from PyQt5.QtCore import (QT_VERSION_STR, PYQT_VERSION_STR,
                          QCoreApplication)
from PyQt5 import QtWidgets

# the versions: the Qt the binding wraps, the binding,
# and the platform the app runs on
print("Qt:", QT_VERSION_STR)
print("PyQt:", PYQT_VERSION_STR)
print("platform:", QCoreApplication.platformName())
# "xcb" (the X11), "windows", "cocoa" (the macOS)

# a minimal "is the loop alive" check - the app object,
# a timed event, the loop:
app = QtWidgets.QApplication(sys.argv)
from PyQt5.QtCore import QTimer
timer = QTimer()
timer.timeout.connect(lambda: (print("loop alive"),
                               timer.stop()))
timer.start(200)
app.exec()
print("loop exited cleanly")

The verification is the version print plus the loop check: the QT_VERSION_STR (the Qt the binding wraps - the 5.15.x for the PyQt5, the 6.x for the PyQt6), the PYQT_VERSION_STR (the binding), and the platformName() (the xcb for the X11, the windows, the cocoa for the macOS) - the three that confirm the app is running on the toolkit and the platform it expects. The loop check is the QTimer that fires once into the app.exec() (the timeout signal, the stop, the clean exit) - the proof that the event loop dispatches, which is the runtime the app will run on. The platform note is the one that matters per OS: on the macOS the pip wheel is the framework build (the cocoa platform, the .app bundle the packaging chapter addresses), on the Windows the wheel is the binary (the windows platform, the DLLs bundled), and on the Linux the xcb platform needs the platform plugin (the pip wheel carries it, the distro build uses the system's). Both checks are one-liners, and running them in a fresh interpreter before the first real window is the setup discipline.

The Platform Specifics

# the Linux: the xcb platform plugin needs the X11 libraries
# (present on the desktop; the headless case is the offscreen
# plugin for the test / the CI):
#   QT_QPA_PLATFORM=offscreen python app.py   # the no-display

# the macOS: the framework build; the app as a .app bundle
# is the packaging chapter's job (the PyInstaller --windowed
# on the mac makes the bundle); the code signing is the
# distribution's (the notarization for the Gatekeeper)

# the Windows: the wheel bundles the Qt DLLs; the app's
# distribution is the frozen exe (the packaging chapter)
# or the python + the site-packages (the venv)

# the cross-platform check: the SAME code runs on the three;
# the platform differences are the plugin (the xcb / the
# cocoa / the windows), the path separators (the os.path
# or the pathlib, not the hardcoded /), and the dialog
# look (the platform's native dialog, the Qt's default)

The platform specifics are the three notes the setup must carry. The Linux: the xcb platform plugin needs the X11 libraries (present on the desktop), and the headless case (the test, the CI) is the QT_QPA_PLATFORM=offscreen - the platform that renders to a buffer without a display, which is the environment the testing chapter uses. The macOS: the pip wheel is the framework build (the cocoa platform), and the app as a .app bundle is the packaging chapter's job (the PyInstaller --windowed on the mac makes the bundle), with the code signing and the notarization the distribution's concern. The Windows: the wheel bundles the Qt DLLs, and the distribution is the frozen exe (the packaging chapter) or the venv with the site-packages. The cross-platform check is the one that defines the value: the same code runs on the three, and the platform differences are the plugin (the xcb/cocoa/windows), the path separators (the os.path or the pathlib, never the hardcoded /), and the dialog look (the platform's native, the Qt's default) - the three the code keeps platform-neutral and the three the deployment handles.

The Licensing Decision

The PyQt5 and the PyQt6 are available under two licenses, and the choice is the app's distribution. The GPL (the GNU General Public License) is the free path: the app can use and distribute PyQt under the GPL, on the condition that the app itself is GPL-compatible (the app's source available under the GPL, for the distributed app) - the path for the open-source app and the internal tool. The commercial Qt license is the paid path: the app uses PyQt (and the Qt it wraps) under the commercial terms, which allows the app to be closed-source and under any license - the path for the proprietary product. The PyQt6 added the specific clause (the BSD-like terms for the PyQt6 itself under the conditions the Riverbank license states), which the legal review of the specific PyQt6 terms confirms. The decision is the one the app's license makes: the open-source or the internal app takes the GPL path (no cost, the source-available condition), the proprietary distributed product takes the commercial license (the cost, the closed-source freedom), and the review is against the specific PyQt version's license text, because the terms are the version's and the chapter's note is the orientation, not the legal advice. The practical rule: the GPL for the open and the internal, the commercial for the closed-source product, and the license text of the specific PyQt version is the authority the decision cites.

Summary

The installation is the binding line choice - the pip install PyQt5 (the Qt 5, the stable) or the PyQt6 (the Qt 6, the current), the wheel bundling the Qt libraries so no system Qt is needed, or the distro package for the system-managed path, plus the PyQt5-tools for the pyuic/pyrcc design tools. The verification is the version print (the QT_VERSION_STR, the PYQT_VERSION_STR, the platformName()) and the QTimer loop check, and the platform specifics are the three notes - the Linux xcb plugin (the offscreen for the headless test), the macOS framework build (the .app bundle the packaging chapter makes), the Windows bundled DLLs. The licensing is the GPL (the free path, the app's source-available condition) or the commercial Qt license (the paid path, the closed-source freedom), decided by the app's own distribution - the open-source and the internal app on the GPL, the proprietary product on the commercial, with the specific PyQt version's license text the authority the decision cites.