2026 年维护说明:本文末尾的日期明确档案中保留了完整的 2019 年正文,包括
xcb错误、个人修复说法和图片引用,仅规范化行尾空白。旧文没有说明 Ubuntu 发行版、Python/PyQt/Qt 版本、缺失库或安装的软件包,因此不能支持一条万能修复命令。下面的维护版会先诊断当前解释器、Qt 安装、显示会话和准确的加载失败原因,再更改软件包。
Table of Contents
选择一种安装路线
PyQt5 可以来自 Ubuntu 软件包,也可以来自 Riverbank 的 PyPI wheel。两种路线都有效,但安装和运行应用所用的解释器必须一致。记录 python --version、安装命令以及最终解析出的 PyQt 和 Qt 版本。
Ubuntu 软件包与系统 Python
Ubuntu 在受支持发行版的 Universe 组件中发布 python3-pyqt5:
sudo apt update
sudo apt install python3-pyqt5
python3 -c 'from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR; print("PyQt", PYQT_VERSION_STR, "Qt", QT_VERSION_STR)'
这条路线使用 Ubuntu 的 Python 和 Qt 打包。如果 APT 找不到该软件包,请确认已经启用当前 Ubuntu 发行版的正确软件源;不要添加从另一发行版复制来的软件源。
项目虚拟环境与 Riverbank wheel
要建立项目隔离环境:
sudo apt update
sudo apt install python3-venv
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install PyQt5
python -c 'from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR; print("PyQt", PYQT_VERSION_STR, "Qt", QT_VERSION_STR)'
Riverbank 说明 PyQt5 wheel 会安装对应的 Qt 库,但仍然依赖显示服务器和平台插件运行库等操作系统设施。环境启用期间应使用其中的 python;不要用一个解释器安装、另一个解释器启动。避免使用 sudo pip,因为它会越过系统软件包管理边界。
运行一个最小且可测试的应用
把下面代码保存为 hello_pyqt5.py:
import sys
from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR, QTimer
from PyQt5.QtWidgets import QApplication, QLabel
app = QApplication(sys.argv)
label = QLabel(f"PyQt {PYQT_VERSION_STR} / Qt {QT_VERSION_STR}")
label.resize(320, 80)
label.show()
if "--smoke-test" in sys.argv:
QTimer.singleShot(0, app.quit)
raise SystemExit(app.exec_())
先检查 Python 语法,再从普通 Ubuntu 桌面终端启动:
python3 -m py_compile hello_pyqt5.py
python3 hello_pyqt5.py
在虚拟环境中,把 python3 换成 python。桌面测试的预期结果是出现一个显示 PyQt 和 Qt 版本的可见窗口。--smoke-test 开关只用于本指南后面的自动显示测试。
xcb 错误能证明什么,不能证明什么
历史错误是:
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized.

截图只能证明历史错误类型,不能证明缺少的是某个特定 Ubuntu 软件包。
Qt 使用 QPA 平台插件把 GUI 代码连接到窗口系统。在 X11 上,这个插件是 xcb。“已找到”只表示 Qt 找到了候选插件文件;如果缺少共享库、插件与 Qt 库不兼容、插件路径被覆盖,或没有可用显示,加载或初始化仍会失败。
不要一开始就安装一长串随机的 libxcb 软件包。先确定故障属于哪一类。
1. 确认解释器和 Qt 树
使用发生故障的同一个解释器运行诊断:
command -v python3
python3 --version
python3 - <<'PY'
import PyQt5
from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR, QLibraryInfo
print("PyQt package:", PyQt5.__file__)
print("PyQt version:", PYQT_VERSION_STR)
print("Qt version:", QT_VERSION_STR)
print("Qt plugins:", QLibraryInfo.location(QLibraryInfo.PluginsPath))
PY
在虚拟环境中,每一行都使用 python。如果 PyQt5.__file__ 和插件目录指向意外的安装位置,应先修正解释器或环境,而不是在不同 Qt 树之间复制插件文件。
Qt 警告,全局 QT_PLUGIN_PATH 会干扰其他 Qt 安装。检查覆盖变量:
env | grep -E '^QT_(PLUGIN_PATH|QPA_PLATFORM_PLUGIN_PATH|QPA_PLATFORM)=' || true
作为诊断,在不使用两个插件路径覆盖变量的情况下重试:
env -u QT_PLUGIN_PATH -u QT_QPA_PLATFORM_PLUGIN_PATH python3 hello_pyqt5.py
如果这样可以运行,应从环境配置中删除过期覆盖,而不是换成另一个硬编码插件路径。
2. 确认显示是否存在
检查会话,但不要更改访问控制:
printf 'DISPLAY=%snWAYLAND_DISPLAY=%snXDG_SESSION_TYPE=%sn'
"${DISPLAY-}" "${WAYLAND_DISPLAY-}" "${XDG_SESSION_TYPE-}"
普通 Ubuntu 本地桌面会话通常会提供可用的显示连接。在普通 SSH shell、容器、服务或 CI 任务中,两个显示变量可能都不可用。安装另一个 XCB 库无法创建显示服务器或显示认证。
不要把 xhost + 当作捷径:它会削弱 X 服务器访问控制。请使用具有正确认证的桌面/远程显示会话,或使用下面的隔离式无头测试方法。
3. 让 Qt 说明插件为何失败
Qt 提供 QT_DEBUG_PLUGINS 以输出详细的插件加载诊断:
QT_DEBUG_PLUGINS=1 python3 hello_pyqt5.py 2>qt-plugin-debug.log
查看 libqxcb.so 附近的第一条加载器错误,而不只是最后的通用消息:
grep -E 'libqxcb|not found|cannot open|undefined symbol|version' qt-plugin-debug.log
日志可能包含本地路径和环境信息。请将其保密,分享前先删除或遮盖敏感部分。
4. 检查已安装 xcb 插件的依赖
用同一个解释器输出平台插件目录:
qt_plugin_dir="$(python3 -c 'from PyQt5.QtCore import QLibraryInfo; print(QLibraryInfo.location(QLibraryInfo.PluginsPath))')"
find "$qt_plugin_dir/platforms" -maxdepth 1 -name 'libqxcb.so' -print
对于由 Ubuntu 或所选虚拟环境安装的可信插件,检查未解析的库:
ldd "$qt_plugin_dir/platforms/libqxcb.so" | grep 'not found' || true
如果没有缺失项,就不要继续安装 XCB 软件包。回到调试日志,寻找不兼容符号/版本、意外插件树或显示连接失败。
如果缺少某个具体共享对象,把准确文件名映射到当前 Ubuntu 发行版的软件包:
sudo apt update
sudo apt install apt-file
sudo apt-file update
apt-file search libxcb-xinerama.so.0
例如,只有当诊断明确指出缺少 libxcb-xinerama.so.0,并且当前发行版的软件包索引把它映射到 libxcb-xinerama0 时,才安装这个包。软件包名和依赖可能随发行版与架构改变。安装有证据支持的软件包后,重新运行 ldd、冒烟测试和真实应用。
5. 区分桌面、offscreen 与虚拟 X 测试
这些测试回答不同的问题。
Qt offscreen 冒烟测试不使用 xcb,只构造控件:
QT_QPA_PLATFORM=offscreen python3 hello_pyqt5.py --smoke-test
成功说明 Python 能导入 PyQt5,并能用现有 offscreen 插件构造示例;它不能证明 xcb 或桌面显示可用。
要在无头 CI 中测试 X11/xcb 路径,使用隔离的虚拟 X 服务器:
sudo apt update
sudo apt install xvfb xauth
xvfb-run -a python3 hello_pyqt5.py --smoke-test
xvfb-run 会建立 X 认证数据、启动 Xvfb、运行命令并在命令退出后清理。Xvfb 成功而桌面启动失败,说明应关注真实桌面会话、认证或环境。offscreen 成功而 Xvfb 失败,则应继续检查 xcb 及其 X11 依赖。
不要在 Wayland 桌面上全局强制 QT_QPA_PLATFORM=xcb。平台是否可用取决于安装的 Qt 构建和会话。如果自动选择正常工作,就保持不变;只有在有记录的诊断命令中临时覆盖。
6. 先看故障特征,再选择动作
| 证据 | 可能的边界 | 下一步 |
|---|---|---|
ModuleNotFoundError: No module named 'PyQt5' | 解释器错误,或其中没有安装 PyQt5 | 选择预期的 APT 或虚拟环境路线,并用同一个解释器验证 |
libNAME.so... => not found 或 “cannot open shared object file” | 缺少运行库 | 用 apt-file search 查询准确文件名,安装映射到当前发行版的软件包,再重跑诊断 |
| “undefined symbol”、Qt 版本不兼容或意外插件路径 | Qt/插件树混合 | 删除过期路径覆盖并重建一套一致安装;不要手工复制 libqxcb.so |
| “could not connect to display” 或显示变量为空/不可用 | 会话/显示边界 | 根据需求使用已登录桌面、已配置远程显示、offscreen 冒烟测试或 Xvfb |
| offscreen 通过,Xvfb 失败 | X11/xcb 加载或初始化 | 检查 QT_DEBUG_PLUGINS 和 ldd 结果 |
| Xvfb 通过,桌面失败 | 桌面会话、认证或环境 | 比较两个会话的显示变量和 Qt 覆盖变量 |
| 最小测试都通过,真实应用失败 | 应用专用导入、插件、渲染或启动代码 | 逐步缩减应用并捕获第一条新增错误 |
7. 避免掩盖原因的“修复”
- 不要安装所有以
libxcb开头的软件包;只安装由缺失文件证明需要的软件包。 - 不要在系统 Qt、wheel 自带 Qt、Conda、IDE 或其他应用之间复制平台插件。
- 不要把教程中的路径全局写入
QT_PLUGIN_PATH、QT_QPA_PLATFORM_PLUGIN_PATH或LD_LIBRARY_PATH。 - 不要用
sudo运行应用,以访问其他用户的显示或软件包安装。 - 不要使用
sudo pip修改 Ubuntu 的 Python 环境。 - 不要把
QT_QPA_PLATFORM=offscreen当成交互式桌面应用的修复方法;它特意不生成可见桌面窗口。 - 检查本地路径和环境数据之前,不要公开插件调试日志。
可复现验证记录
把以下结果与问题单或项目一起保存:
lsb_release -ds和dpkg --print-architecture输出的 Ubuntu 发行版与架构;- 准确的 Python 可执行文件和版本;
- PyQt/Qt 版本与
PyQt5.__file__; - 安装路线,以及适用时锁定的项目依赖;
DISPLAY、WAYLAND_DISPLAY和XDG_SESSION_TYPE是否存在,但不要分享会话秘密;- Qt 插件目录与第一条相关的
QT_DEBUG_PLUGINS加载错误; - 未解析的
ldd项与使用的 Ubuntu 软件包映射; - 语法、offscreen、Xvfb 与真实桌面测试结果;
- 所做修改及其回滚方法。
这份记录能区分可复现修复与“装了某个 XCB 相关东西后就好了”。
---
2019 年原始导出(来源档案)
档案边界:以下代码块内是
out/posts/2019-04-23-run-pyqt5-in-ubuntu-1898/index.md中 post 1898 的完整正文,导出内容日期为 2019 年 4 月 23 日。措辞、标点、弯引号、图片路径和个人说法均未改变,仅规范化行尾空白。请勿把它当作当前修复步骤执行。
qt.qpa.plugin: Could not load the Qt platform plugin “xcb” in “” even though it was found. This application failed to start because no Qt platform plugin could be initialized.
I accidentally installed the xcb plugin and the problem solved.

---
