Qt编写自定义控件22-蚂蚁线
一、前言
关于蚂蚁线控件,相信很多用过PS的人都知道,在选中某个区域以后,边上的线条会有一种动态流动的效果,这种效果就叫做蚂蚁线,百科的解释是:动物的一种本能现象,领头的蚂蚁以随机的路线走向食物或洞穴,第二只蚂蚁紧跟其后以相同的路线行走,每一个后来的蚂蚁紧跟前面蚂蚁行走,排成一条线的现象。在图像影像软件中表示选区的动态虚线,因为虚线闪烁的样子像是一群蚂蚁在跑,所以俗称蚂蚁线。在Photoshop,After ffect等软件中比较常见。
在Qt项目中,有时候可能也会需要用到此控件,比如表格选中,或者某个图像区域选中,某个面板区域选中等,这样就可以更直观的展示选中的区域。
蚂蚁线控件的核心比较简单,就是qpainter中qpen的setDashPattern,这个可以设置连续几个值表示当前的黑白分割区域的位置线段和长度等,查看头文件得知void setDashPattern(const QVector &pattern);为此我们要做的就是搞个定时器不断更新这个值即可,当蚂蚁线走到末尾,则重新赋值,每次只需要将前面两个长度更新就行。
二、实现的功能
- 1:可设置蚂蚁线的长度
- 2:可设置蚂蚁线的宽度=粗细
- 3:可设置蚂蚁线的步长
- 4:可设置蚂蚁线的流动速度
- 5:可设置蚂蚁线的颜色
- 6:可设置蚂蚁线的形状
三、效果图
四、头文件代码
#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();
}
}
六、控件介绍
- 超过146个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
- 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
- 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
- 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
- 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
- 每个控件默认配色和demo对应的配色都非常精美。
- 超过130个可见控件,6个不可见控件。
- 部分控件提供多种样式风格选择,多种指示器样式选择。
- 所有控件自适应窗体拉伸变化。
- 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
- 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
- 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
- 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。
七、SDK下载
- SDK下载链接:https://pan.baidu.com/s/1tD9v1YPfE2fgYoK6lqUr1Q 提取码:lyhk
- 自定义控件+属性设计器欣赏:https://pan.baidu.com/s/1l6L3rKSiLu_uYi7lnL3ibQ 提取码:tmvl
- 下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo。
- 自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。
- 目前已提供26个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
- 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
- widget版本(QQ:517216493)qml版本(QQ:373955953)三峰驼(QQ:278969898)。
- 涛哥的知乎专栏 Qt进阶之路 https://zhuanlan.zhihu.com/TaoQt
- 欢迎关注微信公众号【高效程序员】,C++/Python、学习方法、写作技巧、热门技术、职场发展等内容,干货多多,福利多多!
Qt编写自定义控件22-蚂蚁线的更多相关文章
- Qt编写自定义控件二动画按钮
现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原 ...
- Qt编写自定义控件11-设备防区按钮控件
前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...
- Qt编写自定义控件10-云台仪表盘
前言 做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程 ...
- Qt编写自定义控件12-进度仪表盘
前言 进度仪表盘主要应用场景是标识一个任务进度完成的状况等,可以自由的设置范围值和当前值,为了美观还提供了四种指示器(圆形指示器/指针指示器/圆角指针指示器/三角形指示器),各种颜色都可以设置,其中的 ...
- Qt编写自定义控件25-自定义QCustomPlot
一.前言 上次在写大屏数据可视化电子看板系统时候,提到过改造QCustomPlot来实现柱状分组图.横向柱状图.横向分组图.鼠标悬停提示等.这次单独列出来描述,有很多人疑问为啥不用QChart,或者e ...
- Qt编写自定义控件16-魔法老鼠
前言 五一期间一直忙着大屏电子看板软件的开发,没有再去整理控件,今天已经将大屏电子看板的所有子窗口都实现了任意停靠和双击独立再次双击最大化等功能,过阵子有空再写一篇文章介绍其中的技术点.魔法老鼠控件, ...
- Qt编写自定义控件15-百分比仪表盘
前言 百分比仪表盘,主要的应用场景是展示销售完成率.产品合格率等,也可以作为一个进度百分比展示,可以独立设置对应的标题文字,标题文字的颜色和整体的颜色都可以单独设置,建议设置成统一的风格,这样会显得更 ...
- Qt编写自定义控件14-环形进度条
前言 环形进度条,用来展示当前进度,为了满足大屏UI的需要特意定制,以前有个叫圆环进度条,不能满足项目需要,只能重新定做,以前的进度间距不能自适应分辨率,而且当前进度对应的反的进度不能单独设置颜色,即 ...
- Qt编写自定义控件13-多态进度条
前言 多态进度条,顾名思义,有多重状态,其实本控件主要是用来表示百分比进度的,由于之前已经存在了百分比进度条控件,名字被霸占了,按照先来先得原则,只好另外取个别名叫做多态进度条,应用场景是,某种任务有 ...
随机推荐
- hibernate使用注解生成表,有时无法生成数据表的原因
待生成表中有字段“desc”或“descripe”等和hibernate关键字,导致和hibernate冲突
- Vs2017 FrameWork EF Mysql 控制台应用
1 运行环境 vs2017 Net FromWork 4.6.2 手动版 没有 ado.net 实体数据模型 2 NuGet MySql.Data.Entity 6.10.9, MySq ...
- Ajax长连接和SignalR(刷新客户端数据)的区别
ajax实现长连接 <%@ page language="java" import="java.util.*" pageEncoding=" ...
- OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)
简介 Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同. 首先,uniform是全局的(Global).全局意味着uniform变量必须在每个着 ...
- react-router和react-router-dom的区别
RR4 本次采用单代码仓库模型架构(monorepo),这意味者这个仓库里面有若干相互独立的包,分别是: react-router React Router 核心 react-router-dom 用 ...
- DataSet,DataTable,DataView、DataRelation
一.创建Dataset和DataTable DataSet ds = new DataSet();//DataSetName默认为"NewDataSet" DataTable ta ...
- Oracle12c-ADG搭建
实验环境: 角色 IP hostname CDB name db_unique_name pdb name 版本 主 192.168.0.115 Node11 cdb1 cdb_p pdb1 12.2 ...
- 24-SQLServer存储空间的分配和使用情况
一.总结 1.SQLServer中的数据库有的时候会有多个数据文件组或者多个数据文件的情况,该博客就是讨论当有多个数据文件时,表的数据会怎么存储,存储在哪些数据文件中. 2.首先SQLServer中的 ...
- 聊聊我理解的ANSI C、ISO C、GNU C、POSIX C
几句话了解C标准之间的关系 C语言标准 早期的计算机汇编语言是与机器平台紧密耦合的,为了屏蔽这种耦合,增加代码的可移植性,C语言随机出现. 二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异, ...
- 27、AOP-AOP功能测试
27.AOP-AOP功能测试 AOP : [动态代理]指程序运行期间动态的将某段代码切入到制定方法位置进行运行的编程方式. 导入AOP模块:Spring AOP(spring-aspects) 定义一 ...