简介: QStylePenStyleCustomDashLine使用,使用自定义风格样式的画笔;本篇例子来自绘画 Deepin v20DTKDSlider 控件滑槽。

[TOC]


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


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

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


系列博文:


运行效果:

  • 设计师给的图片:
  • 第一次绘画效果(2019-09-01):
  • 第二次修改效果(2019-09-03):
  • 第三次修改效果(更新2020-07-25:重绘滑动槽细节):


区别:

其中第一次绘画,和第二次绘画滑槽,都是使用划线void QPainter::drawLine(const QLineF &line) 来进行绘画的,之前是使用系统自带的Qt::DotLine风格,而现在是使用自定义样式的Qt::CustomDashLine风格绘画;原因是系统自带Qt::DotLine的虽可以控制pen.setWidthF(3);线的粗细,但是不能控制其高度(保持宽度和间隔不变的情况下);很难长得和设计图一样。


PenStyle介绍:

想看一下enum Qt::PenStyle的官方文档:一共有7(统风格)+1(自定义风格)的样式:


CustomDashLine使用方法:

官方教程如下:使用void setDashPattern(const QVector<qreal> &dashPattern) 函数

译文如下:

将此笔的虚线模式设置为给定模式。这隐式地将笔的样式转换为Qt :: CustomDashLine。
必须将模式指定为偶数个正条目,其中条目1,3,5 …是短划线,而2,4,6 ……是空格。例如:

QPen pen;
QVector dashes;
qreal space = 4;
dashes << 1 << space << 3 << space << 9 << space << 27 << space;
pen.setDashPattern(dashes);

仪表板图案以笔宽度为单位指定;例如宽度为10的长度为5的长度为50像素。请注意,宽度为零的笔相当于宽度为1像素的化妆笔。
每个破折号也受制于帽子样式,因此带有方帽设置的短划线将在每个方向上延伸0.5像素,从而导致总宽度为2。
请注意,默认的上限样式是Qt :: SquareCap,这意味着方形线末端覆盖终点并超出线宽的一半。
另请参见setStyle(),dashPattern(),setCapStyle()和setCosmetic()。

其中具体使用如下:

其中便是绘画一条(自定义)的线:其线的一个完整的周期为(单位为像素):

1(线段) 4(间隔) 3(线段) 4(间隔) 9(线段) 4(间隔) 27(线段) 4(间隔)

注意:其中dashes只能够出现为偶数对,不可为奇数个;


用于项目:

首先贴出第一次的”绘画滑槽“代码(局部):

QPen pen;
//绘画 滑槽(线)
if (opt->subControls & SC_SliderGroove) {
    pen.setStyle(Qt::DotLine);
    pen.setWidthF(3);
    pen.setColor(getColor(opt, QPalette::Highlight));
    p->setPen(pen);
    p->setRenderHint(QPainter::Antialiasing);
    p->drawLine(QPointF(rectGroove.left(), rectHandle.center().y()), QPointF(rectHandle.left(), rectHandle.center().y()));
    pen.setColor(getColor(opt, QPalette::Foreground));
    p->setPen(pen);
    p->drawLine(QPointF(rectGroove.right(), rectHandle.center().y()), QPointF(rectHandle.right(), rectHandle.center().y()));
}

另外一个绘画方法是,在规定大小矩形内,绘画n多个小矩形,充当滑槽,但是可能需绘画多个小矩形来实现(考虑到效率开销),得到细密的线的效果;其使用for循环 遍历绘画很多次 (同样也是大的),所以此方法被否定了。

只需要上面的pen.setStyle(Qt::DotLine);(第四行)修改为如下代码

pen.setStyle(Qt::CustomDashLine);
    QVector<qreal> dashes;
    qreal space = 1.3;
    dashes << 0.1 << space;
    pen.setDashPattern(dashes);

即可得到这次的效果:


更新2020-07-25:重绘滑动槽细节

前面一段时间,Slider 实际上是没有完全 100% 达到设计图的样式要求的(惭愧),后腾出手来,决定将其改一下,还原设计图的滑槽样式:其中具体的详细提交如下:#8895abb7

其中的困难点是,设置画笔的高度、宽度、实线与虚线的间隔(要求在苹果的高分屏放大看细节后,且不会出现错误的模糊偏移);

在开发的普通屏幕中,可以安装 eog, 然后左上角的设置里关掉平滑,再次查看图片放大看,就不会糊掉了,可以清晰的看到下面的实先和虚线偏移重叠;

给上最后的解决参数方案。

pen.setStyle(Qt::CustomDashLine);
pen.setWidth(4);
pen.setBrush((opt->activeSubControls & SC_SliderHandle) ? getColor(opt, QPalette::Highlight) : opt->palette.highlight());
pen.setDashOffset(0);
pen.setDashPattern(QVector<qreal>()<< 0.5 << 0.25);  // 这个数值是最接近其原图, 且放大之后,不会有模糊偏移
pen.setCapStyle(Qt::FlatCap);
p->setPen(pen);
p->setRenderHint(QPainter::Antialiasing);

放上一张最后的效果图:

开心分享:

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


系列地址:

QtExamples

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