如何仅覆盖一个属性:Qt StyleSheet 中的值对 [英] How to override just one property:value pair in Qt StyleSheet

查看:59
本文介绍了如何仅覆盖一个属性:Qt StyleSheet 中的值对的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 OSX Mavericks 上编写新手 Qt5 代码,并且只想覆盖给定小部件的样式表的一个属性:值对.

I am writing newbie Qt5 code on OSX Mavericks and would like to override just one property:value pair of the StyleSheet for a given widget.

如果我运行以下自包含的演示代码:

If I run the following self-contained demonstration code:

#include <QApplication>
#include <QMainWindow>
#include <QtGui>
#include <QPushButton>

int
main( int argc, char *argv[] ) {
    QApplication app( argc, argv );

    QMainWindow* mw = new QMainWindow();

    QPushButton* AButton = new QPushButton( "A Button", mw );

    mw->show();

    return app.exec();
}

我得到了一个带有 Macintosh 风格默认值的漂亮按钮——圆角、按下时的标准 OSX 蓝色等:

I get a nice pushbutton with Macintosh style defaults -- rounded corners, standard OSX-blue color when pressed, etc.:

但是,如果我将样式表设置为使背景按钮颜色为红色,则在此过程中我似乎丢失了所有其他 OSX 样式默认值——不再有圆角、标准边距等:

If however I set the stylesheet to make the background button color red, it seems I lose all the other OSX style defaults in the process -- no more rounded corners, standard margins, etc.:

#include <QApplication>
#include <QMainWindow>
#include <QtGui>
#include <QPushButton>

int
main( int argc, char *argv[] ) {
    QApplication app( argc, argv );

    QMainWindow* mw = new QMainWindow();

    QPushButton* AButton = new QPushButton( "A Button", mw );

    AButton->setStyleSheet("QPushButton { background-color: red; }");

    mw->show();

    return app.exec();
}

结果如下:

如何只覆盖一个 property:value 对,同时保留小部件的其余样式元素,例如在上面的示例中,将背景颜色设为红色,但保持所有边框、边距等相同?

How can I override just one property:value pair while preserving the rest of the style elements for the widget, e.g. in the example above make the background color red but keep all the border rounding, margins etc. the same?

非常感谢

推荐答案

您在评论中的分析是对 QApplication::setStyleSheet() 将完全替换当前不正确的活动样式.当前样式被替换为 QStyleSheetStyle 是对的.但是, QStyleSheetStyle 将其绘图委托给原始样式,在您的情况下为 Mac 样式.如果您查看 QStyleSheetStyle 的来源,你会在很多地方看到这个,调用 baseStyle()->drawControl().

Your analysis in your comment that a call to QApplication::setStyleSheet() will completely replace the currently active style is incorrect. You are right that a the current style is replaced with QStyleSheetStyle. However, QStyleSheetStyle delegates its drawing to the original style, in your case the Mac style. If you look at the source of QStyleSheetStyle, you'll see this in many places, calls to baseStyle()->drawControl().

这意味着样式表适用于任何样式.现在,它显然在你的情况下不起作用,那么发生了什么?如果样式表规则不能应用于基本样式,QStyleSheetStyle 会退回到以 Windows 样式绘制.这意味着某些样式表规则运行良好,而其他样式表规则会触发回退.您的规则触发了回退.

This means stylesheets work on any style. Now, it clearly didn't work in your case, so what happened? QStyleSheetStyle falls back to drawing in the Windows style if the style sheet rules can't be applied to the base style. That means that some style sheet rules work nicely, while others will trigger the fallback. Your rules triggered the fallback.

我认为没有记录哪些规则会触发回退.为此,我们需要查看源代码,在这种情况下 QStyleSheetStyle::drawControl().我们将在其中找到以下内容:

I don't think it's documented which rules trigger the fallback. For that we need to look at the source, in this case QStyleSheetStyle::drawControl(). We'll find the following in there:

case CE_PushButton:
    if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
        if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
                ((btn->features & QStyleOptionButton::HasMenu) && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator))) {
            ParentStyle::drawControl(ce, opt, p, w);
            return;
        }
    }

ParentSyle 是后备 Windows 样式.您的规则 background-color 使 rule.hasPalette() 返回 true,从而触发回退.

ParentSyle is the fallback Windows style. Your rule background-color makes rule.hasPalette() return true, therefore triggering the fallback.

这篇关于如何仅覆盖一个属性:Qt StyleSheet 中的值对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆