简介: QStyle
之PenStyle
的CustomDashLine
使用,使用自定义风格样式的画笔;本篇例子来自绘画 Deepin v20
的 DTK
的 DSlider
控件滑槽。
[TOC]
本文初发于 “偕臧的小站“,同步转载于此。
编程环境: deepin 15.11 x64 专业版
Kernel: x86_64 Linux 4.15.0-30deepin-generic
编程软件: Qt Creator 4.8.2 (Enterprise)
, Qt 5.9.8
系列博文:
QStyle
自定义重绘QSlider
控件- QStyle之PenStyle的CustomDashLine使用 【更新:更加精准的绘画滑槽】
- 重绘的QStyle中sizeFromContents()没有被调用
- QStyle自定义重绘QSlider控件二(重要)
运行效果:
- 设计师给的图片:
- 第一次绘画效果(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;
QVectordashes;
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);
放上一张最后的效果图:
开心分享:
因为有着许许多多的热心网友的无私分享,从他们的博客中学习成长,学会很多,故也不辞辛苦也将自己的项目或经验整理成博客的形式,也提供给一起大家学习探讨与交流
系列地址:
欢迎 star
和 fork
这个系列的 QT / DTK 学习,附学习由浅入深的目录。