QStyle自定义重绘QSlider控件二

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

本博文的简述or解决问题?

详情: 见简介


编程环境: 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_SliderThicknessSlider总的高度 = 滑块高度+刻度高度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;
}

开心分享:

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


系列地址:

QtExamples

欢迎 starfork 这个系列的 QT / DTK 学习,附学习由浅入深的目录。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偕臧x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值