Qt Gui 第十九章

1、Qt样式表

.qss文件;跟html的css文件格式差不多。

例如:selector1, selector2。。。 {property1: value1; property2: value2; 。。。。}   表示多个选择器,对应多个属性值;

也可以在代码中直接编写;例如:

// 指向全局的设置QLineEdit的背景色为黄色;
qApp->setStyleSheet("QLineEdit{background-color:yellow;}");
// 要使用的dialog设置QLineEdit的背景色为黄色;
CandyDialog w;
w.setStyleSheet("QLineEdit{background-color:yellow;}");

当要使用文件导入的时候

    CandyDialog w;
    QFile file(":/qss/candy.qss");
    file.open(QIODevice::ReadOnly);
    w.setStyleSheet(file.readAll());

因为candy.qss是资源文件,则需要在qrc文件中指明;

<RCC>
<qresource>
<file>qss/candy.qss</file>
</qresource>
</RCC>

 

qss的编写

1、颜色

可以使用rgb()、rgba()、 #RRGGBB;也可以使用调色板:palette(Base)  ;渐进的调色:QLinearGradient、QRadialGradient、QConicalGradient;例如:

    background-color:qlineargradient(x1:0,y1:0,x2:1,y2:1,
                                   stop:0 white,stop:0.4 gray,
                                   stop:1 green);

2、图片

image: url(:/images/down-arrow.png); 或者 border-image: url(:/images/button.png) 4 8 12 16; 模型即:url(image.png) top right bottom left; 即上面的横切线、右边的竖切线,下面的横切线,左边的竖切线;如果没有指定竖直,则表明边界均为0;即0 0 0 0

当切割完之后,长方形的四个角被固定;从而在拉伸的时候以这四个角进行拉伸;如图所示

当只指定一个数值的时候,则表示上下左右都是那个数值,而不是只指top是那个数值;

3、padding

padding是指文字要放的位子偏移;模型是:padding: top right bottom left;   如果要单独指定的话,则是padding-top 或者其他的方位;如上图所示;如果要将contents rectangle的区域覆盖到border rectangle 则需要将padding的值设置为负数;

即移动contents rectangle通过padding来完成;

4、indicator的使用;例如

QLineEdit,
QListView {
    color: rgb(127,0,63);
    background-color: rgb(255,255,241);
}

如上qss所示,有两个indicator(QLineEdit和QListView)共同使用花括号里面的属性值;

indicator也可以是:control:subcontrol的方式如:QComboBox:editable、QCheckBox:checked:hover、QCheckBox:!checked:hover  也可以是如上所示的逻辑非

 

5、杂项

当使用圆角的时候,可以使用

border-radius: 10px; 表示半径为10像素的圆作为圆角

border: 2px groove gray; 表示两像素的灰色凹槽

font: bold 10pt; 使用10号加粗的字体

QComboBox * {font: 9pt;}  表示QComboBox的子项用的字号是9

 

二、子类化QStyle

当使用到custom style的时候,则需要在使用到这个子类化控件之前,先设置进qapplication; 例如:要将BronzeStyle这个子类化的控件加到程序中,则需要在用到这个控件之前先操作:QApplication::setStyle(new BronzeStyle);

1、 drawComplexControl和drawControl

drawComplexControl和drawControl 两个函数都是用于绘制控件的;具体看要绘制的控件是简单控件还是复杂控件。比如:PushButton、PushButtonBevel、PushButtonLabel、RadioButton等简单的控件用drawControl即可;复杂的控件绘制则用drawComplexControl;具体看qcommonstyle.cpp里面对这两个函数的实现。

在这两个函数的使用时候,尽量不要用widget这个参数。

最好使用如下类似的标记红色的方式进行操作;

    case CE_PushButton:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
。。。。。。
        }
        break;

2、polish

在绘制窗口之前,会先调用polish(QPalette &pal)进行初始化画板;如果要对画板进行特殊的设置,则可以重写该函数。

复制代码
void BronzeStyle::polish(QPalette &palette)
{
    QPixmap backgroundImage(":/images/background.png");
    QColor bronze(207, 155, 95);
    QColor veryLightBlue(239, 239, 247);
    QColor lightBlue(223,223,239);
    QColor darkBlue(95, 95, 191);

    palette = QPalette(bronze);
    palette.setBrush(QPalette::Window, backgroundImage);
    palette.setBrush(QPalette::BrightText, Qt::white);
    palette.setBrush(QPalette::Base, veryLightBlue);
    palette.setBrush(QPalette::AlternateBase, lightBlue);
    palette.setBrush(QPalette::Highlight, darkBlue);
    palette.setBrush(QPalette::Disabled, QPalette::Highlight,
                     Qt::darkGray);
}
复制代码

当具体到某个控件的时候,也可以调用polish(同函数,不同参数)polish(QWidget *widget)

比如:当想对鼠标进入指定控件时候产生重绘事件

void BronzeStyle::polish(QWidget *widget)
{
    if (qobject_cast<QAbstractButton*>(widget)
            || qobject_cast<QAbstractSpinBox*>(widget) )
        widget->setAttribute(Qt::WA_Hover, true);
}

当绘制完成之后,则需要将刚才产生重绘的属性设置回false;

void BronzeStyle::unpolish(QWidget *widget)
{
    if (qobject_cast<QAbstractButton*>(widget)
            || qobject_cast<QAbstractSpinBox*>(widget))
        widget->setAttribute(Qt::WA_Hover, false);
}

3、standardIconImplementation

获取用户界面上的标准图标;通过这个函数则可以调整标准图标的一些颜色,透明度等。

 

4、subControlRect和subElementRect

subControlRect是获取控件当中各个部件的尺寸;例如:SpinBoxDown、SpinBoxUp、SpinBoxEditField等。。。都是具体的控件的子部件;

复制代码
QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
                                   SubControl sc, const QWidget *widget) const
{
    QRect ret;
    switch (cc) {
#ifndef QT_NO_SLIDER
    case CC_Slider:
        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
            int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);

            switch (sc) {
            case SC_SliderHandle: {
                int sliderPos = 0;
                int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
                bool horizontal = slider->orientation == Qt::Horizontal;
                sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum,
                                                    slider->sliderPosition,
                                                    (horizontal ? slider->rect.width()
                                                                : slider->rect.height()) - len,
                                                    slider->upsideDown);
                if (horizontal)
                    ret.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness);
                else
                    ret.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len);
                break; }
            case SC_SliderGroove:
                if (slider->orientation == Qt::Horizontal)
                    ret.setRect(slider->rect.x(), slider->rect.y() + tickOffset,
                                slider->rect.width(), thickness);
                else
                    ret.setRect(slider->rect.x() + tickOffset, slider->rect.y(),
                                thickness, slider->rect.height());
                break;
            default:
                break;
            }
            ret = visualRect(slider->direction, slider->rect, ret);
        }
        break;
.........
     default:
        qWarning("QCommonStyle::subControlRect: Case %d not handled", cc);
    }
    return ret;
View Code
复制代码

subElementRect则是获取子元素的尺寸;例如:PushButtonContents、PushButtonFocusRect、CheckBoxIndicator、HeaderLabel等元素

复制代码
QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
                                   const QWidget *widget) const
{
    Q_D(const QCommonStyle);
    QRect r;
    switch (sr) {
    case SE_PushButtonContents:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
            int dx1, dx2;
            dx1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
            if (btn->features & QStyleOptionButton::AutoDefaultButton)
                dx1 += proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
            dx2 = dx1 * 2;
            r.setRect(opt->rect.x() + dx1, opt->rect.y() + dx1, opt->rect.width() - dx2,
                      opt->rect.height() - dx2);
            r = visualRect(opt->direction, opt->rect, r);
        }
        break;
..................
    default:
        break;
    }
    return r;
}
复制代码

 

posted @   LCAC  阅读(373)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示