一、配置环境变量
1、方法1:于终端中配置环境变量
在启动YourApp 之前,于当前终端中配置环境变量:
export QTDIR=~/Qt5.14.2/5.14.2/gcc_64
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QT_PLUGIN_PATH=$QTDIR/plugins
export QML2_IMPORT_PATH=$QTDIR/qml
export QT_IM_MODULE=qtvirtualkeyboard
export QT_QPA_PLATFORM=xcb
然后再运行:
cd /Your/Software/build/Bin
./YourApp
2、方法2:于代码中添加环境变量设置 推荐
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
注意:上述代码一定要放在你app创建的前面,即放在下述代码前面。
QGuiApplication app(argc, argv);
二、问题分析
从运行日志和目录检查结果中一步步推出来,下面逐条分析
1、"QtQuick.VirtualKeyboard 主模块有"
依据:在执行:
ls ~/Qt5.14.2/5.14.2/gcc_64/qml/QtQuick/VirtualKeyboard
输出是:
libqtquickvirtualkeyboardplugin.so plugins.qmltypes qmldir Settings Styles
其中 qmldir 是 QML 模块的定义文件。一个目录里有 qmldir,就说明这个 QML 模块被正确安装了。所以可以确定 QtQuick.VirtualKeyboard 主模块存在。
2、"QtQuick.VirtualKeyboard.Styles、Settings 子模块有"
依据:同样在上面的 ls 输出里,可以看到 Settings 和 Styles 两个子目录。并且你执行了:
find ~/Qt5.14.2 -name "qmldir" -path "VirtualKeyboard" 2>/dev/null
输出里有:
/home/yourname/Qt5.14.2/5.14.2/gcc_64/qml/QtQuick/VirtualKeyboard/Styles/qmldir
/home/yourname/Qt5.14.2/5.14.2/gcc_64/qml/QtQuick/VirtualKeyboard/Settings/qmldir
这两个子目录下都有 qmldir,说明它们也被安装了。
3、"但 QtQuick.VirtualKeyboard.Plugins 子模块没有安装到 qml/ 目录下"
依据:还是上面那条 find 命令,它专门找所有路径里带 VirtualKeyboard 的 qmldir 文件。结果只有三个:
.../VirtualKeyboard/qmldir
.../VirtualKeyboard/Styles/qmldir
.../VirtualKeyboard/Settings/qmldir
没有出现 ".../VirtualKeyboard/Plugins/qmldir"。如果 Plugins 子模块被安装了,就一定会有这个文件。因此可以断定:QtQuick.VirtualKeyboard.Plugins 没有安装到 qml/ 目录下。
4、"而 Keyboard.qml 第 38 行有一句 import QtQuick.VirtualKeyboard.Plugins 2.14"
依据:在执行:
grep -rl "VirtualKeyboard.Plugins" ~/Qt5.14.2/5.14.2/Src/qtvirtualkeyboard/src/ 2>/dev/null
输出里包含:
/home/yourname/Qt5.14.2/5.14.2/Src/qtvirtualkeyboard/src/virtualkeyboard/content/components/Keyboard.qml
这说明源码中的 Keyboard.qml 文件里确实引用了 VirtualKeyboard.Plugins。
另外,在最早的运行日志里,有一行错误:
qrc:/QtQuick/VirtualKeyboard/content/components/Keyboard.qml:38 module "QtQuick.VirtualKeyboard.Plugins" is not installed
这直接指出:Keyboard.qml 第 38 行尝试导入 QtQuick.VirtualKeyboard.Plugins,但系统报告该模块未安装。
5、"这个 import 失败后,Keyboard.qml 加载失败 → InputPanel.qml 加载失败 → Login.qml 加载失败 → StackView.initialItem 加载失败 → 整个界面白屏"
依据:全部来自你最早提供的运行日志。日志里的错误是链式出现的:
qrc:/main.qml:30:9: QML StackView: initialItem: qrc:/YourActivity/main.qml:21 Type Login unavailable
qrc:/YourActivity/Login.qml:130 Type InputPanel unavailable
qrc:/QtQuick/VirtualKeyboard/content/InputPanel.qml:127 Type Keyboard unavailable
qrc:/QtQuick/VirtualKeyboard/content/components/Keyboard.qml:38 module "QtQuick.VirtualKeyboard.Plugins" is not installed
从下往上读:
(1)Keyboard.qml 因为缺少 QtQuick.VirtualKeyboard.Plugins 而加载失败;
(2)于是 InputPanel.qml 里用到的 Keyboard 类型不可用,InputPanel 加载失败;
(3)于是 Login.qml 里用到的 InputPanel 类型不可用,Login 加载失败;
(4)于是 main.qml 里 StackView 的 initialItem(即 Login)不可用;
(5)最终整个界面无法显示,表现为白屏。
所以"白屏"不是显卡或窗口系统的问题,而是 QML 组件链式加载失败导致的。
三、环境变量逐行解释
执行的这组命令:
export QTDIR=~/Qt5.14.2/5.14.2/gcc_64
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QT_PLUGIN_PATH=$QTDIR/plugins
export QML2_IMPORT_PATH=$QTDIR/qml
export QT_IM_MODULE=qtvirtualkeyboard
export QT_QPA_PLATFORM=xcb
1、export QTDIR=~/Qt5.14.2/5.14.2/gcc_64
作用:定义一个名为 QTDIR 的环境变量,值为你的 Qt 5.14.2 安装目录。
为什么这么做:后面几行都要引用这个目录。先定义成一个变量,写起来短,改起来也方便。如果以后换了 Qt 版本,只改这一行就行。
export 的含义:把变量导出到当前 shell 及其子进程中。这样你启动的 YourApp 才能读到这些变量。
2、export PATH=QTDIR/bin:PATH
作用:把 $QTDIR/bin 加到 PATH 的最前面。
为什么这么做:PATH 决定了你在终端里输入命令时,系统去哪些目录找可执行文件。把 Qt 的 bin 放最前面,可以保证你运行 qmake、moc、uic 等工具时,优先使用你安装的 Qt 5.14.2 版本,而不是系统自带的 Qt。
$PATH 放在后面:保留原来的搜索路径,只是让 Qt 的路径优先。
3、export LD_LIBRARY_PATH=QTDIR/lib:LD_LIBRARY_PATH
作用:告诉动态链接器,在加载 .so 共享库时,优先去 $QTDIR/lib 里找。
为什么这么做:YourApp 依赖很多 Qt 库,比如 libQt5Core.so、libQt5Gui.so、libQt5Qml.so 等。系统里可能装了别的 Qt 版本,如果不指定,程序可能链接到系统 Qt,导致版本不匹配、符号找不到、崩溃或白屏。把 $QTDIR/lib 放最前面,就能保证程序使用你安装的 Qt 5.14.2 的库。
4、export QT_PLUGIN_PATH=$QTDIR/plugins
作用:指定 Qt 插件的搜索路径。
为什么这么做:Qt 有很多插件,比如平台插件(platforms/libqxcb.so)、输入法插件(platforminputcontexts/libqtvirtualkeyboardplugin.so)等。QT_PLUGIN_PATH 会告诉 Qt 去 QTDIR/plugins 下找这些插件。如果不设置,Qt 可能去系统目录找,而系统目录里可能没有虚拟键盘插件,或者版本不对。你之前检查过 QTDIR/plugins/platforminputcontexts/ 下有 libqtvirtualkeyboardplugin.so,设置这个变量就能让 Qt 找到它。
5、export QML2_IMPORT_PATH=$QTDIR/qml
作用:指定 QML 模块的搜索路径。
为什么这么做:QML 引擎在解析 import QtQuick.VirtualKeyboard 2.14 这类语句时,会去 QML2_IMPORT_PATH 指定的目录里找对应的模块。你的虚拟键盘 QML 模块安装在 $QTDIR/qml/QtQuick/VirtualKeyboard。如果不设置这个变量,QML 引擎可能去系统 QML 目录找,那里可能没有安装,或者版本不对。设置后,它就能找到你安装的虚拟键盘模块,InputPanel、Keyboard 等组件才能正常加载。这是解决白屏的关键之一。
6、export QT_IM_MODULE=qtvirtualkeyboard
作用:指定 Qt 的输入法模块为 qtvirtualkeyboard。
为什么这么做:QML 中的 InputPanel 是虚拟键盘的输入面板,它依赖 Qt 的输入法框架。QT_IM_MODULE 告诉 Qt 使用哪个输入法插件。设置为 qtvirtualkeyboard 后,Qt 才会加载虚拟键盘作为输入法,InputPanel 才能正常工作。如果不设置,InputPanel 可能找不到输入法后端,导致加载失败。这也是解决白屏的关键之一。
7、export QT_QPA_PLATFORM=xcb
作用:指定 Qt 的平台插件为 xcb,也就是使用 X11 后端。
为什么这么做:你最早的日志里有一行警告:
Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
这说明你的桌面环境是 Wayland,但 Qt 默认可能没有正确适配,或者虚拟键盘在 Wayland 下有问题。强制使用 xcb(X11 后端)可以避开 Wayland 的兼容性问题,让界面稳定显示。在很多 Qt 应用白屏、闪烁、输入法异常的情况下,切到 xcb 是常见的解决办法。
8、总结:这些变量为什么能解决白屏
(1)QML2_IMPORT_PATH 让 QML 引擎找到了 QtQuick.VirtualKeyboard 模块;
(2)QT_IM_MODULE 让 InputPanel 能挂上虚拟键盘输入法;
(3)QT_PLUGIN_PATH 让 Qt 找到了虚拟键盘的平台输入法插件;
(4)LD_LIBRARY_PATH 保证程序用的是你安装的 Qt 5.14.2 库;
(5)QT_QPA_PLATFORM=xcb 避开了 Wayland 的潜在问题。
这些条件同时满足后,Keyboard.qml 不再因为缺少模块而失败,链式加载恢复正常,界面就不再白屏了。
9、补充建议
这些 export 只在当前终端有效。关掉终端或换一个终端,就需要重新执行。建议把它们写进一个启动脚本,例如:
#!/bin/bash
export QTDIR=~/Qt5.14.2/5.14.2/gcc_64
export PATH=QTDIR/bin:PATH
export LD_LIBRARY_PATH=QTDIR/lib:LD_LIBRARY_PATH
export QT_PLUGIN_PATH=$QTDIR/plugins
export QML2_IMPORT_PATH=$QTDIR/qml
export QT_IM_MODULE=qtvirtualkeyboard
export QT_QPA_PLATFORM=xcb
cd /Your/Software/build/Bin
./YourApp