Qt GUI主题看起来老套

Qt GUI theme looks old-fashioned

当我自己从源代码交叉编译 Qt 5.8.0 并使用它从 Qt Widgets for Microsoft Windows, it looks old-fashioned, as if it were running on Windows 2000, as shown in the left window below. However, if I compile the exact same program using the pre-built mingw-w64-x86_64-qt5-static package (version 5.8.0-1) from MSYS2 构建 Qt "Dynamic Layouts" 示例时,它看起来像一个不错的现代 Windows 应用程序,如下右window所示。我怎样才能修复我的 Qt 版本,使用它构建的 GUI 看起来更漂亮?是否缺少配置选项?

要研究的一件事是 QWindowsVistaStyle class。我注意到当我在 MSYS2 中编译我的程序时,我必须添加 -luxtheme 因为 class 引用了那里的一些函数,比如 GetThemeColor。这些功能仅在 Windows Vista 及更高版本中可用。当我在 Linux 上使用自己的 Qt 进行交叉编译时,我不需要那个库,所以也许 class 在我的构建中被禁用了。

交叉编译的 Qt 构建细节

我使用 commit f51d834 of my nixcrpkgs repository. If you look at the code in that commit, it will show you exactly what commands were run to build the mingw-w64 cross-compiler, and build Qt, and build the Qt examples, including Dynamic Layouts. You can build it yourself if you install Nix, download nixcrkpkgs, and then run nix-build -A pkgs.i686-w64-mingw32.qt.base-examples in the nixcrpkgs directory. You can see my build recipe for the Qt package in that commit.

构建了交叉编译的 Qt 和看起来很老的动态布局示例

MSYS2 构建详细信息

我运行this script in a MINGW64 shell in MSYS2 to build the example and got good results. It relies on the mingw-w64-x86_64-qt5-static package from MSYS2. You can see the build recipe for that package.

小部件

基于 Qt 的 GUI 将根据您的 OS 自动 select 默认主题。如果你想覆盖它,你正在寻找 QApplication 的 setStyle 方法,它允许你定义用于你的应用程序的样式,而不管它在 OS 上运行。

QApplication::setStyle("fusion");

根据文档,支持以下内容:

  • "windows"
  • "fusion"
  • "windowsxp"
  • "macintosh"

支持的主题取决于您的平台,可以使用插件进行扩展。


编辑:此答案针对 Qt 配置步骤正确检测到 OS 的情况,而您只想更改使用的主题。在所描述的情况下,错误的主题是 selected,已在 OP 的答案中修复。

Qt Quick

如果您的 GUI 基于 QtQuick 而不是 Widgets,您可以使用 QQuickStyle::setStyle("Material"); 来自定义您希望使用的主题。

有关详细信息,您可以查看该文档页面:

如果你查看 Qt 5.8.0 的 src/widgets/configure.json 文件,你可以看到它检查 uxtheme.h 的存在,并且 uxtheme.h 是编译的前提条件windowsxp风格,这是编译windowsvista风格的前提条件。通过查看 Qt 的 config.log,我发现 uxtheme.h 测试失败了。我不确定为什么,但这可能是因为 uxtheme.h 不能单独包含在内;您需要事先包含 windows.h。通过在配置 Qt 后查看 src/widgets/qtwidgets-config.pri 文件,我确认确实没有启用 windowsxpwindowsvista 样式。它有一个将要编译的样式列表,windowsvista 不是列表。

我尝试将 -style-windowsxp -style-windowsvista 选项添加到 Qt 的配置命令,但这些选项只会导致错误,因为 uxtheme.h 测试失败,而它是编译这些主题的先决条件。

我的解决方案是将此补丁应用到 Qt 5.8.0 以完全跳过 uxtheme 测试:

diff -ur qt58-orig/src/widgets/configure.json qt58/src/widgets/configure.json
--- qt58-orig/src/widgets/configure.json        2017-05-28 02:07:07.625626151 -0700
+++ qt58/src/widgets/configure.json     2017-06-27 21:25:52.752628339 -0700
@@ -28,11 +28,6 @@
     },

     "tests": {
-        "uxtheme": {
-            "label": "uxtheme.h",
-            "type": "files",
-            "files": [ "uxtheme.h" ]
-        }
     },

     "features": {
@@ -57,7 +52,7 @@
         },
         "style-windowsxp": {
             "label": "WindowsXP",
-            "condition": "features.style-windows && config.win32 && !config.winrt && tests.uxtheme",
+            "condition": "features.style-windows && config.win32 && !config.winrt",
             "output": [ "styles" ]
         },
         "style-windowsvista": {

我不确定为什么 MSYS2 包运行良好,因为我在他们的构建脚本中没有看到任何这样的补丁。

我在从静态 Qt 5.6.3 升级到静态 5.12.0 时遇到了同样的问题。我尝试使用 QApplication::setStyle() 手动设置 "windowsvista" 样式并注意到它在调试时返回 null 后解决了它。事实证明,在 5.12.0 中,windowsvista 样式是它自己的独立插件,您需要 link 反对 plugins/styles/qwindowsvistastyle.lib 并将 Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) 添加到包含您的主要功能的 cpp 文件.之后就不用手动设置样式了,自动选择。

我从Qt5.9.1升级到Qt5.12后遇到了同样的问题。

放置 qwindowsvistastyle.dll,我发现它位于 Qt.12.0\msvc2017_64\plugins\styles,需要放置在我的 applicationDir\styles 目录中。

我知道这个主题有点过时,但我找到了一个简单的解决方案来解决这个问题,但在 Qt 6 中仍然无法正常工作

我的环境

Windows 11,QT 6.2.2,CLion,嵌入式 CMake,MSVC 2019 编译器

将此行添加到 CMakeLists.txt 的末尾:

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${QT_INSTALL_PATH}/plugins/styles/qwindowsvistastyle${DEBUG_SUFFIX}.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/styles")