关于蚂蚁线控件,相信不少用过PS的人都知道,在选中某个区域之后,边上的线条会有一种动态流动的效果,这种效果就叫作蚂蚁线,百科的解释是:动物的一种本能现象,领头的蚂蚁以随机的路线走向食物或洞穴,第二只蚂蚁紧跟其后以相同的路线行走,每个后来的蚂蚁紧跟前面蚂蚁行走,排成一条线的现象。在图像影像软件中表示选区的动态虚线,由于虚线闪烁的样子像是一群蚂蚁在跑,因此俗称蚂蚁线。在Photoshop,After ffect等软件中比较常见。
在Qt项目中,有时候可能也会须要用到此控件,好比表格选中,或者某个图像区域选中,某个面板区域选中等,这样就能够更直观的展现选中的区域。
蚂蚁线控件的核心比较简单,就是qpainter中qpen的setDashPattern,这个能够设置连续几个值表示当前的黑白分割区域的位置线段和长度等,查看头文件得知void setDashPattern(const QVector
#ifndef ANTLINE_H #define ANTLINE_H /** * 蚂蚁线控件 整理:feiyangqingyun(QQ:517216493) 2018-8-31 * 1:可设置蚂蚁线的长度 * 2:可设置蚂蚁线的宽度=粗细 * 3:可设置蚂蚁线的步长 * 4:可设置蚂蚁线的流动速度 * 5:可设置蚂蚁线的颜色 * 6:可设置蚂蚁线的形状 */ #include <QWidget> #include <QVector> #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include <QtDesigner/QDesignerExportWidget> #else #include <QtUiPlugin/QDesignerExportWidget> #endif class QDESIGNER_WIDGET_EXPORT AntLine : public QWidget #else class AntLine : public QWidget #endif { Q_OBJECT Q_ENUMS(LineStyle) Q_PROPERTY(int lineLen READ getLineLen WRITE setLineLen) Q_PROPERTY(int lineWidth READ getLineWidth WRITE setLineWidth) Q_PROPERTY(int lineStep READ getLineStep WRITE setLineStep) Q_PROPERTY(int lineSpeed READ getLineSpeed WRITE setLineSpeed) Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor) Q_PROPERTY(LineStyle lineStyle READ getLineStyle WRITE setLineStyle) public: enum LineStyle { LineStyle_Rect = 0, //矩形 LineStyle_RoundedRect = 1, //圆角矩形 LineStyle_Ellipse = 2, //椭圆 LineStyle_Circle = 3 //圆形 }; explicit AntLine(QWidget *parent = 0); ~AntLine(); protected: void paintEvent(QPaintEvent *event); private: int lineLen; //线条长度 int lineWidth; //线条宽度 int lineStep; //每次移动的步长 int lineSpeed; //线条流动的速度 QColor lineColor; //线条颜色 LineStyle lineStyle; //线条样式 int dashes; //线条长度 int spaces; //空白长度 QVector<double> dashPattern;//线条样式数据 QTimer *timer; //更新定时器 private slots: void updateValue(); public: int getLineLen() const; int getLineWidth() const; int getLineStep() const; int getLineSpeed() const; QColor getLineColor() const; LineStyle getLineStyle() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //设置线条长度 void setLineLen(int lineLen); //设置线条宽度 void setLineWidth(int lineWidth); //设置线条步长 void setLineStep(int lineStep); //设置线条速度 void setLineSpeed(int lineSpeed); //设置线条颜色 void setLineColor(const QColor &lineColor); //设置线条样式 void setLineStyle(const LineStyle &lineStyle); }; #endif // ANTLINE_H
#pragma execution_character_set("utf-8") #include "antline.h" #include "qpainter.h" #include "qevent.h" #include "qtimer.h" #include "qdebug.h" AntLine::AntLine(QWidget *parent) : QWidget(parent) { lineLen = 6; lineWidth = 2; lineStep = 1; lineSpeed = 100; lineColor = QColor(0, 0, 0); lineStyle = LineStyle_Circle; dashes = lineLen; spaces = lineLen; dashPattern.clear(); for (int i = 0; i < 20; ++i) { dashPattern << lineLen; } //启动定时器更新线条 timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(updateValue())); timer->start(lineSpeed); } AntLine::~AntLine() { if (timer->isActive()) { timer->stop(); } } void AntLine::paintEvent(QPaintEvent *) { int width = this->width(); int height = this->height(); int side = qMin(width, height); //绘制准备工做,启用反锯齿 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing); //设置画笔宽度+颜色+点阵样式 QPen pen; pen.setWidth(lineWidth); pen.setColor(lineColor); pen.setDashPattern(dashPattern); painter.setPen(pen); //根据不一样的样式绘制不一样的线条 if (lineStyle == LineStyle_Rect) { painter.drawRect(0, 0, width, height); } else if (lineStyle == LineStyle_RoundedRect) { painter.drawRoundedRect(0, 0, width, height, 5, 5); } else if (lineStyle == LineStyle_Ellipse) { painter.drawEllipse(0, 0, width, height); } else if (lineStyle == LineStyle_Circle) { painter.drawEllipse(width / 2 - side / 2, 0, side, side); } } void AntLine::updateValue() { //当蚂蚁线走到末尾,则从新赋值 if (dashes == lineLen && spaces == lineLen) { dashes = 0; spaces = 0; } if (dashes == 0 && spaces < lineLen) { spaces = spaces + lineStep; } else if (spaces == lineLen && dashes < lineLen) { dashes = dashes + lineStep; } //每次只须要将前面两个长度更新就行 dashPattern[0] = dashes; dashPattern[1] = spaces; update(); } int AntLine::getLineLen() const { return this->lineLen; } int AntLine::getLineWidth() const { return this->lineWidth; } int AntLine::getLineStep() const { return this->lineStep; } int AntLine::getLineSpeed() const { return this->lineSpeed; } QColor AntLine::getLineColor() const { return this->lineColor; } AntLine::LineStyle AntLine::getLineStyle() const { return this->lineStyle; } QSize AntLine::sizeHint() const { return QSize(100, 100); } QSize AntLine::minimumSizeHint() const { return QSize(20, 20); } void AntLine::setLineLen(int lineLen) { if (this->lineLen != lineLen) { this->lineLen = lineLen; dashes = lineLen; spaces = lineLen; dashPattern.clear(); for (int i = 0; i < 20; ++i) { dashPattern << lineLen; } update(); } } void AntLine::setLineWidth(int lineWidth) { if (this->lineWidth != lineWidth) { this->lineWidth = lineWidth; update(); } } void AntLine::setLineStep(int lineStep) { if (this->lineStep != lineStep) { this->lineStep = lineStep; update(); } } void AntLine::setLineSpeed(int lineSpeed) { if (this->lineSpeed != lineSpeed) { this->lineSpeed = lineSpeed; update(); } } void AntLine::setLineColor(const QColor &lineColor) { if (this->lineColor != lineColor) { this->lineColor = lineColor; update(); } } void AntLine::setLineStyle(const AntLine::LineStyle &lineStyle) { if (this->lineStyle != lineStyle) { this->lineStyle = lineStyle; update(); } }