QT 对话框的样式不正确

Posted

技术标签:

【中文标题】QT 对话框的样式不正确【英文标题】:QT Dialog has incorrect styling 【发布时间】:2020-02-14 15:17:40 【问题描述】:

我一直在尝试各种方法来创建需要从主应用程序生成的新对话框。

我创建了一个设计师表单,没有什么特别之处,并在上面放置了一些库存小部件。一旦我终于让它从主应用程序正确启动,我注意到小部件没有样式。按钮没有边框或浮雕,所有文本均为白色,按钮和 LineEdit 对象的背景颜色为灰色。用于启动对话框的代码如下:

    UpdateDialog dialog(NULL);
    dialog.setModal(true);
    dialog.exec();

我认为它可能是从父小部件继承的,所以我在对话框对象的构造函数中将 NULL 作为父小部件传递,但它仍然发生。

我在网上找到了一个类似问题的答案,建议您可以通过为基本上看起来像这样的对话框设置样式表来覆盖从父级继承的样式表:

    #objectName 

但这没有效果。

创建后应用于小部件的样式似乎有效,好像我使用以下行,按钮上的文本颜色变为黑色:

    dialog->setStyleSheet("color: rgb(0,0,0)");

有谁知道导致这种行为的原因是什么?如果重要的话,我们在 Scientific Linux (RHEL 6) 上使用 Qt 5.6.1。

编辑:这是对话框的图片。

标签下方应该有一个 LineEdit,以及它右侧的一个按钮,然后 LineEdit 下面还有两个按钮。不幸的是,图片质量并没有让您看到它,但是按钮应该在的位置有一个非常微弱的白色文本,所以它们就在那里,只是没有样式。

编辑:这种样式似乎也适用于我从上面看到的更新对话框中生成的文件对话框。

【问题讨论】:

随机猜测:您尝试了吗:QApplication::setStyle( "WindowsVista" );QApplication::setStyle( "Fusion" ); setupUi? @ChrisMM 我应该指定这是一个 Linux 应用程序。但是不,没有应用程序范围的样式表。 @Jesper 是的,setupUi 被调用了。 @ChrisMM 我添加了一张图片,如果它可以帮助您了解我遇到的问题。 【参考方案1】:

Qt does not have 拥有强大的视觉识别。相反,它试图在其所有目标平台上提供原生外观。所有操作系统都包含一些外观定制功能,但在这方面 Linux 是特殊的,因为没有像 Windows 和 macOS 那样的单一、独特的用户界面,而是有几个。两个著名的 Linux(和其他类 Unix 操作系统)桌面是 Gnome 和 KDE。一些发行版默认安装 Gnome,还有一些发行版安装其他发行版。大多数都允许安装两者,用户可以在登录屏幕或桌面配置设置中选择一个。

我以前从未尝试过 Scientific Linux,但我知道 Fedora,因此在 VirtualBox VM 中安装 SL6 以查看是否可以重现您的问题并不是什么大问题(我不能!)。我注意到的是 SL6 默认为 Gnome 桌面(如 RH 和 Fedora,顺便说一句)。它不包含 Qt5,并且很难在其上安装 Qt5 开发环境,因为它附带了一个过时的 GCC 编译器。不过,可以在其上部署 Qt 5.6 应用程序和库。我也用这个命令在 VM 中安装了 KDE:

    sudo yum -y groupinstall "KDE Desktop"

当然,SL6 不包括 KDE Plasma,因为它需要 Qt5。它是基于 Qt4.6 的 KDE4.3。所以,在这个版本中,更正我之前的评论,更改/检查 KDE 样式的配置命令是:

    kcmshell4 style

KDE4 的默认样式是 Oxygen,正如我根据您的图片推断的那样。 KDE 程序的配色方案可以用这个命令来配置:

    kcmshell4 colors

为了尝试您的方案,我制作了一个简单的 Qt5 Widgets 程序,我可以将它与依赖的 Qt5 库一起部署在 VM 上。我已经使用linuxdeployqt 部署了程序所需的库和插件,并创建了一个自包含的目录,以便于传输和安装。无论如何,我想向您展示该程序在我的开发 Linux 机器上的外观,以及我喜欢的暗风主题:

将程序目录部署到SL6 VM后,在默认的Gnome桌面下运行,如下所示:

这是在 KDE 下运行程序时的样子:

请记住,我们正在查看相同程序的相同版本,只是更改了运行环境。仅供参考,我已经对我的程序进行了一些检测,包括在 main() 函数中的这个调试语句:

     qDebug() << QStyleFactory::keys();

在 Linux 上打印此输出:

(“Windows”、“GTK+”、“Fusion”)

并且还在主窗口构造函数中包含了这个调试语句:

    qDebug() << this->style();

该语句的输出取决于桌面环境。在 Gnome(基于 gtk+ 工具包)下,它会输出如下内容:

QGtkStyle(0x11b39f0, name = "gtk+")

在 KDE 桌面下输出:

QFusionStyle(0x1428990, name = "fusion")

希望此时你能像我一样推断出你的问题的根源一定是你的SL6中KDE下的颜色配置。为了证明这个理论,请运行其他一些 Qt 程序,看看它们是否显示相同的不合适的颜色。在这种情况下,我的建议是修复该配置(通过运行 kcmshell4 colors)而不是更改程序来强制使用某些固定的配色方案,因为良好的桌面集成对于大多数 Linux 用户来说是一项宝贵的资产。

无论如何,如果你想在你的程序中创建一个硬编码的固定配色方案,我给你这个例子,你可以将它包含在你的 main.cpp 中以应用于整个程序。

static QPalette qt_fusionPalette()

    QColor backGround(239, 239, 239);
    QColor light = backGround.lighter(150);
    QColor mid(backGround.darker(130));
    QColor midLight = mid.lighter(110);
    QColor base = Qt::white;
    QColor disabledBase(backGround);
    QColor dark = backGround.darker(150);
    QColor darkDisabled = QColor(209, 209, 209).darker(110);
    QColor text = Qt::black;
    QColor hightlightedText = Qt::white;
    QColor disabledText = QColor(190, 190, 190);
    QColor button = backGround;
    QColor shadow = dark.darker(135);
    QColor disabledShadow = shadow.lighter(150);

    QPalette fusionPalette(Qt::black,backGround,light,dark,mid,text,base);
    fusionPalette.setBrush(QPalette::Midlight, midLight);
    fusionPalette.setBrush(QPalette::Button, button);
    fusionPalette.setBrush(QPalette::Shadow, shadow);
    fusionPalette.setBrush(QPalette::HighlightedText, hightlightedText);

    fusionPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow);

    fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
    fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198));
    fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
    return fusionPalette;


int main(int argc, char *argv[])

    QApplication::setPalette(qt_fusionPalette());
    QApplication a(argc, argv);
    qDebug() << QStyleFactory::keys();

    MainWindow w;
    w.show();
    return a.exec();

这个浅色调色板与标准 Qt 的“Fusion”palette 相同。如果您喜欢深色方案,您可以找到here。

【讨论】:

在这个系统上运行了几个 Qt 应用程序,但没有一个表现出这种行为。它只出现在我创建的对话框中,并且文件选择器对话框是从对话框中的一个按钮产生的。生成此对话框的父应用程序中没有出现任何问题,该应用程序生成的任何其他子对话框也没有出现。 在这种情况下,对话框的 QPalette 已被您的代码或其他东西修改。正如我所说,我无法重现您的问题,因此我无法提供任何其他建议,除非您可以创建一个最小的可重现示例。 如果您使用 Gnome 登录并在该桌面环境下运行您的程序,这将是一个有用的诊断。 所以在查看了应用程序的其余部分之后,似乎有一个应用程序范围的调色板。在您引起我注意之前,我不知道调色板,因为我对 Qt 的 UI 部分还是很陌生。我尝试在小部件上设置标准调色板以覆盖应用程序范围的调色板,它确实改变了一些东西,但仍然看不到。我将尝试您在上面定义的静态调色板,但就我而言,这已经解决了。 我很高兴你终于解决了这个问题,但是...... 在Qt中也可以将样式称为调色板?。那不是真的。 QPaletteQStyle 是两个不同的互补类。 QStyle 提供并使用 standardPalette。在您的情况下:QStyle 使用QPalette 提供的颜色绘制按钮。顺便说一句,QPushButton 有一个 flat property,它也会影响其外观(使其看起来“扁平”)。

以上是关于QT 对话框的样式不正确的主要内容,如果未能解决你的问题,请参考以下文章

C++ Qt库 如何修改对话框本身的属性(如:最大化、最小化按钮、关闭按钮、边框粗细、颜色等)

qt对话框失去焦点透明

Qt在控件未显示时如何获取正确的控件尺寸

QT开发(二十)——QT对话框

如何存储在 Qt 设置中?

Qt--对话框及其类型布局管理器