TypePHP\Qt
Guide
Widgets
Advanced
Reference
FAQ
  • English
  • 简体中文
GitHub
Guide
Widgets
Advanced
Reference
FAQ
  • English
  • 简体中文
GitHub
  • Guide

    • Guide
    • Installation
    • Installing and Building Qt
    • Quick Start
    • Project Structure
    • Architecture
    • State and View
  • The UI

    • Events and Handlers
    • Properties
    • Layout
    • Dialogs and System Integration
    • Multiple Windows, Tray and Timers
    • Patching

Installing and Building Qt

This page covers Qt itself: which modules you need, how to install them on each OS, and how the build links them. If you only want to get a window on screen, Installation has the short version — come here when Qt is missing, the version differs, or linking fails.

What you actually need

The bridge uses three Qt modules and nothing else:

ModuleProvides
QtCoreQString, containers, event loop, timers, QFileInfo, QDir
QtGuiQIcon, QPixmap, QFont, QClipboard, QScreen, QAction
QtWidgetsevery control: QMainWindow, QPushButton, QTableWidget, …

No QML/Quick, no Network, no Sql — verified against every #include in cpp-src/. So a minimal Qt Widgets install is enough, which is what the commands below give you.

The webview widget does not need extra Qt modules

WidgetTree::webView() uses WebView2 on Windows (Microsoft's Edge engine, not a Qt module — the SDK is vendored in third_party/, and the runtime ships with Windows), WKWebView on macOS (the system WebKit framework, also not a Qt module), and QTextBrowser elsewhere, which is part of QtWidgets. So enabling the webview never means installing QtWebEngine — which would add 1.5–2 GB. See WebView.

Version

Qt 6.0 or newer. The project is developed and tested against 6.9.3; qtphp's automatic detection looks for 6.9.3 specifically, so any other version needs QT_DIR (see below). Qt 5 will not work — the code uses Qt 6 APIs throughout.

Windows

Windows needs two things installed, and they must match each other:

  1. A C++ compiler — MSVC 2022 (or BuildTools). MinGW will not link against an MSVC-built Qt.
  2. Qt 6 built for that same compiler — the msvc2022_64 kit.

Option A — the official online installer (recommended)

Download the Qt Online Installer from https://www.qt.io/download-qt-installer, sign in with a free Qt account, then under Qt → Qt 6.x.x tick exactly:

  • MSVC 2022 64-bit ← the kit you need
  • (optional) Qt 5 Compatibility Module — not used by this project

Skip Sources, Qt Debug Information Files, and any other kit (MinGW, Android, WebAssembly, ARM) — they are gigabytes you will never link.

Install to a path without spaces (the default C:\Qt is fine). qtphp probes C:/Qt/6.9.3/msvc2022_64, D:/Qt/6.9.3/msvc2022_64, and D:/tools/Qt/6.9.3/msvc2022_64.

Option B — aqtinstall (scriptable, no account)

pip install aqtinstall
aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O C:/Qt

Handy for CI or a locked-down machine. Same layout as the official installer, so detection works.

Verify

C:\Qt\6.9.3\msvc2022_64\bin\qmake.exe -query QT_VERSION

You should also see windeployqt.exe in that bin\ directory — qtphp package needs it.

MSVC environment

cl.exe on PATH is not enough; INCLUDE and LIB must be set too. qtphp handles this by calling vcvars64.bat itself — you do not need a "Developer Command Prompt".

macOS

The official Qt installer works, but Homebrew's qtbase is smaller and simpler — it is exactly the three modules above:

brew install qtbase libiconv
  • qtbase is keg-only, so it is not symlinked into /usr/local — that is why qtphp probes /opt/homebrew/opt/qtbase (Apple Silicon) and /usr/local/opt/qtbase (Intel).
  • libiconv is also keg-only; the generated project.macos.yml passes its -L and -rpath explicitly.
  • If you want the full Qt (QML, Charts, …): brew install qt — heavier, and qtphp probes /opt/homebrew/opt/qt as a fallback.

Why macOS links differently

Homebrew's qtbase uses the framework layout: module headers live in lib/Qt<Module>.framework/Headers/, not in include/Qt<Module>/. And Qt's forwarding headers use qualified includes internally (<QtWidgets/qabstractitemview.h>), so the build needs both -I (to resolve bare names) and -F (to resolve qualified ones). The scaffold's project.macos.yml passes both; drop either and the compile fails.

cxx-flags:
  - -F/opt/homebrew/opt/qtbase/lib
  - -I/opt/homebrew/opt/qtbase/lib/QtCore.framework/Headers
  # … Gui, Widgets
ld-flags:
  - -F/opt/homebrew/opt/qtbase/lib
  - -Wl,-framework,QtWidgets
  - -Wl,-framework,QtGui
  - -Wl,-framework,QtCore

Linux

The distro package is the right answer. On Debian / Ubuntu:

apt install -y qt6-base-dev

qt6-base-dev is exactly Core + Gui + Widgets. That single package is enough for the Qt side — the other packages in Installation are for building the private PHP embed runtime, not for Qt.

Other distributions:

DistroCommandQt headers land in
Debian / Ubuntuapt install qt6-base-dev/usr/include/<triple>/qt6/
Fedora / RHELdnf install qt6-qtbase-devel/usr/include/qt6/
Archpacman -S qt6-base/usr/include/qt6/
openSUSEzypper install qt6-base-devel/usr/include/qt6/

Debian's multiarch layout

Debian puts headers under /usr/include/x86_64-linux-gnu/qt6/ (or aarch64-linux-gnu), not /usr/include/qt6/. qtphp detects this with dpkg-architecture -qDEB_HOST_MULTIARCH and generates the right paths.

On Arch / Fedora / openSUSE, edit project.linux.yml and replace the Debian-style paths with the flat /usr/include/qt6 and /usr/lib shown in the table above — that is the one manual step on those distros.

Verify

pkg-config --modversion Qt6Widgets    # needs qt6-base-dev

Pointing the build at a non-default Qt

qtphp's detection covers the common locations for 6.9.3. Anything else — a different version, a custom prefix, a second Qt — needs QT_DIR, which takes precedence over every probed path:

QT_DIR=/path/to/Qt/6.8.2/gcc_64    qtphp build .
QT_DIR=C:/Qt/6.10.0/msvc2022_64    qtphp build .

qtphp new bakes the detected path into project.yml / project.macos.yml / project.linux.yml as plain strings, so you can also edit those directly — that is often simpler for a project you will build repeatedly:

include-paths:
  - /opt/Qt/6.10.0/gcc_64/include
  - /opt/Qt/6.10.0/gcc_64/include/QtCore
  - /opt/Qt/6.10.0/gcc_64/include/QtGui
  - /opt/Qt/6.10.0/gcc_64/include/QtWidgets
link-paths:
  - /opt/Qt/6.10.0/gcc_64/lib

Then confirm:

qtphp doctor     # prints the Qt path it will use

QT_DIR wins over automatic detection, so it works even on a machine that already has a Qt in one of the probed locations. If it points at a directory that does not exist, qtphp warns and falls back to probing.

Troubleshooting

SymptomCause and fix
Qt: 未找到 in doctorQt is not in a probed location → set QT_DIR
fatal error: 'QApplication': No such file or directoryThe include/QtWidgets (or framework -I) path is missing from include-paths
cannot open file 'Qt6Widgets.lib' (MSVC)link-paths lacks <QT>/lib, or you installed the MinGW kit instead of msvc2022_64
undefined reference to 'QApplication::…' (GCC/Clang)link-libs lacks -lQt6Widgets (or -Wl,-framework,QtWidgets on macOS)
'QtWidgets/qabstractitemview.h' file not found (macOS)Missing -F at compile time — see the macOS section
LNK2038 / MSVC runtime mismatchQt was built with a different MSVC toolset than your compiler → reinstall matching kits
could not find or load the Qt platform plugin windows at run timePlugins were not deployed → qtphp build does it for you; see Packaging

Related

  • Installation — the whole toolchain, short version
  • Platforms — per-platform capability matrix
  • Packaging — what must ship alongside the binary
Edit this page on GitHub
Last updated: 10/6/26, 3:13 AM
Prev
Installation
Next
Quick Start