Qt GUI主题看起来过时了。

21

当我自己从源代码中交叉编译Qt 5.8.0,并使用它来构建Qt Widgets中的Qt“Dynamic Layouts”示例程序时,它看起来很老旧,就像在Windows 2000上运行一样(如下面左侧的窗口所示)。然而,如果我使用MSYS2预编译的mingw-w64-x86_64-qt5-static包(版本为5.8.0-1)编译完全相同的程序,则看起来像一个漂亮的现代Windows应用程序(如下面右侧的窗口所示)。如何修复我的Qt版本,使得使用它构建的GUI界面看起来漂亮?我是否错过了某个配置选项?

Left: Qt compiled by me.  Right: Qt compiled by MSYS2 project

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

交叉编译 Qt 构建详细信息

我使用我自己的nixcrpkgs存储库的提交f51d834构建了交叉编译的Qt和旧版的Dynamic Layouts示例。如果您查看该提交中的代码,它将向您展示构建mingw-w64交叉编译器、构建Qt以及构建Qt示例(包括Dynamic Layouts)所运行的确切命令。如果您安装Nix,下载nixcrkpkgs,然后在nixcrpkgs目录中运行nix-build -A pkgs.i686-w64-mingw32.qt.base-examples,则可以自行构建它。您可以在该提交中查看Qt软件包的我的构建配方

MSYS2 构建细节

我在 MSYS2 的 MINGW64 shell 中运行 此脚本 来构建示例,并获得了良好的结果。它依赖于 MSYS2 的 mingw-w64-x86_64-qt5-static 包。你可以查看 该包的构建配方


1
你需要一个清单文件: https://dev59.com/SJfga4cB1Zd3GeqPDvls - Dan Korn
我最终会尝试这个,但是工作的GUI没有清单文件,所以我持怀疑态度。而且你链接的东西和主题或样式无关。 - David Grayson
1
在构建Qt时,小部件样式是可选的。这意味着您可以选择要构建哪些样式,哪些不需要构建。而且,有些样式需要外部依赖项,如果您没有提供这些依赖项,则可以在构建中省略它们。Windows Vista样式确实具有外部依赖关系,并且可能已从您的构建中跳过。要检查运行时可用的样式,可以调用 QStyleFactory::keys() - Benjamin T
谢谢,我在 Qt 源文件中查找了一下,尤其是 src/widgets/configure.json 文件。Windows Vista 和 XP 主题依赖于 "uxtheme.h"。从我的 config.log 中可以看到 uxtheme.h 的测试失败了,但没有说原因。我可能需要在 CFLAGS 中设置 _WIN32_WINNT 或获取有关为什么测试失败的更多详细信息。 - David Grayson
2
也许Qt绘制样式时不依赖Windows DLL,而是自己实现。通过正确配置Qt,我解决了问题;无需使用清单文件。 - David Grayson
5个回答

20

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

我发现需将qwindowsvistastyle.dll放在Qt\5.12.0\msvc2017_64\plugins\styles目录下,并将其放置在我的应用程序目录下的styles目录中。


2
非常感谢!这是一个非常简单的解决方案!点赞! - user10251509
2
对于使用CMake的人,你需要像这样的东西:install(PROGRAMS "$" DESTINATION platforms ) ``` 和 install(PROGRAMS "$<TARGET_FILE:Qt5::QWindowsVistaStylePlugin>" DESTINATION styles ) ``` - Rtbo

11

小部件

基于Qt的图形用户界面将根据您的操作系统自动选择默认主题。如果您想覆盖它,您需要查找QApplication的setStyle方法,该方法允许您定义用于应用程序的样式,无论其运行在哪个操作系统上。

QApplication::setStyle("fusion");

根据文档,以下主题被支持:

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

支持的主题取决于您的平台,并可通过插件进行扩展。


注意:本答案适用于Qt配置步骤正确检测到操作系统,并且您只想更改使用的主题的情况。在所描述的情况下,选择了错误的主题,该问题已在OP的答案中得到修复。

Qt Quick

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

有关更多详细信息,请参阅该文档页面:


我最终会尝试这个,但我持怀疑态度,因为工作的 GUI 没有调用 setStyle。工作的 GUI 使用了完全相同的代码,就像丑陋的 GUI 一样。而且两个 GUI 看起来都像“windows”。 - David Grayson
如果我没记错的话,你展示的左边图片是默认的旧Linux风格,所以应用“Windows”风格应该可以解决这个问题,通过强制使用主题而不是让Qt推断它。 - Adrien Leravat
1
当Qt被正确构建时,它可以推断出正确的主题使用方式;在为Windows编译时,没有必要强制使用Windows主题。 - David Grayson
没错,我会修改我的答案以添加一般信息。赞同你的最后一个回答,它很好地解决了问题! - Adrien Leravat

5
如果您查看Qt 5.8.0中的src/widgets/configure.json文件,您会发现它检查uxtheme.h的存在,并且uxtheme.h是编译windowsxp样式的先决条件,而编译windowsvista样式又是其先决条件。通过查看Qt的config.log,我发现uxtheme.h测试失败了。我不确定原因,但很可能是因为uxtheme.h不能单独包含;您需要先包含windows.h。我验证了src/widgets/qtwidgets-config.pri文件后配置Qt,发现确实没有启用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软件包能够正常工作,因为我没有在他们的构建脚本中看到任何类似的补丁。


4

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


1

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

我的环境

Windows 11,QT 6.2.2,带有嵌入式CMake的CLion,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")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接