關於螞蟻線控件,相信不少用過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(); } }