简介: 修改创建控件时候,的默认矩形大小,重写sizeFromContents()函数,给定默认控件大小

[TOC]


本文初发于 “偕臧的小站“,同步转载于此。


编程环境: deepin 15.11 x64 专业版 Kernel: x86_64 Linux 4.15.0-30deepin-generic

编程软件: Qt Creator 4.8.2 (Enterprise)Qt 5.9.8


系列博文:


更新原因:

因为前一个版本,出现了一个小的bug:那就是,遗漏了当QSlider无需刻度的时候(枚举值为QSlider::NoTicks),会发生opt->rect仍然会比矩形(滑块和滑槽的最小公共矩形)要大;即:没有去除掉用来保留绘画刻度的矩形区域。


运行效果:

上一张最终的运行效果:


QSlider枚举含义:

下面对一些枚举进行一些含义的解释:

枚举 中文含义 Qt文档(其英文含义比较模糊,此处以约定中文含义为准)
PM_SliderThickness Slider总的高度 = 滑块高度+刻度高度 Total slider thickness.
PM_SliderControlThickness 只是滑块的单独高度 Thickness of the slider handle.
PM_SliderLength 只是滑块的长度 Thickness of the slider handle.
PM_SliderLength 只是滑块的长度 Length of the slider.
PM_SliderTickmarkOffset 用作slider的刻度线的高度 The offset between the tickmarks and the slider.
PM_SliderSpaceAvailable 暂时未用到 The available space for the slider to move.

上面表格参考出处代码:qcommonstyle.cpp  4526行

case PM_SliderTickmarkOffset:
    if (const QStyleOptionSlider* sl = qstyleoption_cast<const QStyleOptionSlider*>(opt))
    {
        int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height()
                    : sl->rect.width();
        int thickness = proxy()->pixelMetric(PM_SliderControlThickness, sl, widget);
        int ticks = sl->tickPosition;

        if (ticks == QSlider::TicksBothSides)
            ret = (space - thickness) / 2;
        else if (ticks == QSlider::TicksAbove)
            ret = space - thickness;
        else
            ret = 0;
    }
    else
    {
        ret = 0;
    }
    break;

绘画思路:

上一篇的思路是:

  • 将矩形拆分为三个小矩形
  • 对于每一个矩形进行单独的判断(是否有无),若是有则绘画

而这一篇则是,在第一步骤之前,就进行修改,在sizeFromContents()里面进行初始的矩形计算;

先绘制默认大小,给出默认opt->rect矩形的大小(此时还没有开始计算每一个矩形的大小:将这个最大的矩形进行拆分):

在**virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const override;**里面,填写如下代码:

int sliderContHeight = proxy()->pixelMetric(PM_SliderControlThickness, opt, widget);  //单独滑块高度
            int tickMarkHeight = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, widget);      //单独刻度线高度
            sliderContHeight += tickMarkHeight;

            if (slider->tickPosition == QSlider::NoTicks) {
                sliderContHeight -= tickMarkHeight;
            } else if (slider->tickPosition == QSlider::TicksBothSides) {
                sliderContHeight += tickMarkHeight;
            } else {
            }

            if (slider->orientation == Qt::Horizontal){
                size.setHeight(qMax(size.height(), sliderContHeight));
            } else {
                size.setWidth(qMax(size.width(), sliderContHeight));
            }
        }
        break;
    }
    case CT_MenuBarItem: {
        int frame_margins = DStyle::pixelMetric(PM_FrameMargins, opt, widget);
        size += QSize(frame_margins * 2, frame_margins * 2);
        break;
    }
    default:
        break;
    }

    return size;
}

开心分享:

因为有着许许多多的热心网友的无私分享,从他们的博客中学习成长,学会很多,故也不辞辛苦也将自己的项目或经验整理成博客的形式,也提供给一起大家学习探讨与交流