关键词:
一、前言
广告轮播这个控件做的比较早,是很早以前定制一个电信客户端时候用到的,该客户端需要在首页展示轮播预先设定好的图片,图片的路径可以自由设定,然后轮播的间隔速度可以自由控制,同时该控件还需要提供两种指示器的风格,一种是迷你型的样式,一种是数字型的样式。
本控件很早就做好了,由于当时的QPainter功力不足,还不是很熟悉QPainter,采用的是效率比较低的直接用现有控件堆积而成,比如指示器采用的QLabel,用样式表来控制对应的形状,指示器所在的底部放一个widget,采用左右布局,然后右侧放一个弹簧把指示器label全部顶在左边,至于图片的显示,采用的是样式表中的border-image来设置,开个定时器,到了时间则设置成不同的border-image即可。这种方法虽然效率低了点,但是初学者很容易理解接收,甚至可以做出更多的效果,只要项目对CPU要求不高,也不失为一种还行的办法。
二、实现的功能
- 1:可设置显示的图像
- 2:可添加多个广告
- 3:可设置指示器样式 迷你型样式 数字型样式
- 4:可设置指示器大小
- 5:可设置切换间隔
三、效果图
四、头文件代码
#ifndef ADSWIDGET_H
#define ADSWIDGET_H
/**
* 广告轮播控件 作者:feiyangqingyun(QQ:517216493) 2016-12-22
* 1:可设置显示的图像
* 2:可添加多个广告
* 3:可设置指示器样式 迷你型样式 数字型样式
* 4:可设置指示器大小
* 5:可设置切换间隔
*/
#include <QWidget>
class QLabel;
#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif
class QDESIGNER_WIDGET_EXPORT AdsWidget : public QWidget
#else
class AdsWidget : public QWidget
#endif
Q_OBJECT
Q_ENUMS(BannerStyle)
Q_PROPERTY(int interval READ getInterval WRITE setInterval)
Q_PROPERTY(QSize bannerFixedSize READ getBannerFixedSize WRITE setBannerFixedSize)
Q_PROPERTY(QString imageNames READ getImageNames WRITE setImageNames)
Q_PROPERTY(BannerStyle bannerStyle READ getBannerStyle WRITE setBannerStyle)
public:
enum BannerStyle
BannerStyle_Min = 0, //迷你型样式
BannerStyle_Num = 1 //数字型样式
;
explicit AdsWidget(QWidget *parent = 0);
~AdsWidget();
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
int interval; //自动切换间隔
QSize bannerFixedSize; //导航指示器固定尺寸
BannerStyle bannerStyle; //导航指示器样式
QString imageNames; //导航图片集合字符串
int currentIndex; //当前显示的广告对应索引
QTimer *timer; //定时器轮播广告
QList<QLabel *> labs; //导航标签链表
QList<QString> names; //导航图片链表
QWidget *widgetBg; //存放广告图片的容器
QWidget *widgetBanner; //存放导航指示器的容器
private slots:
void initWidget();
void initForm();
void changedAds();
void changedAds(QLabel *lab);
public:
int getInterval() const;
QSize getBannerFixedSize() const;
BannerStyle getBannerStyle() const;
QString getImageNames() const;
QSize sizeHint() const;
QSize minimumSizeHint() const;
public Q_SLOTS:
void setInterval(int interval);
void setBannerFixedSize(const QSize &bannerFixedSize);
void setBannerStyle(const BannerStyle &bannerStyle);
void setImageNames(const QString &imageNames);
;
#endif // ADSWIDGET_H
五、完整代码
#pragma execution_character_set("utf-8")
#include "adswidget.h"
#include "qevent.h"
#include "qlabel.h"
#include "qlayout.h"
#include "qtimer.h"
#include "qdebug.h"
AdsWidget::AdsWidget(QWidget *parent) : QWidget(parent)
this->initWidget();
this->initForm();
AdsWidget::~AdsWidget()
if (timer->isActive())
timer->stop();
bool AdsWidget::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::MouseButtonPress)
if (obj->inherits("QLabel"))
//先停止定时器,防止按下切换的时候短时间内再度切换
timer->stop();
changedAds((QLabel *)obj);
timer->start(interval);
return QWidget::eventFilter(obj, event);
void AdsWidget::initWidget()
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
verticalLayout->setSpacing(0);
verticalLayout->setContentsMargins(0, 0, 0, 0);
widgetBg = new QWidget(this);
widgetBg->setObjectName(QString::fromUtf8("widgetBg"));
QGridLayout *gridLayout = new QGridLayout(widgetBg);
gridLayout->setSpacing(0);
gridLayout->setContentsMargins(0, 0, 0, 0);
QSpacerItem *verticalSpacer = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding);
gridLayout->addItem(verticalSpacer, 0, 0, 1, 1);
widgetBanner = new QWidget(widgetBg);
widgetBanner->setObjectName(QString::fromUtf8("widgetBanner"));
QHBoxLayout *horizontalLayout = new QHBoxLayout(widgetBanner);
horizontalLayout->setSpacing(3);
gridLayout->addWidget(widgetBanner, 1, 0, 1, 1);
QSpacerItem *horizontalSpacer = new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout->addItem(horizontalSpacer, 1, 1, 1, 1);
verticalLayout->addWidget(widgetBg);
void AdsWidget::initForm()
interval = 3000;
bannerFixedSize = QSize(20, 20);
bannerStyle = BannerStyle_Num;
imageNames.clear();
currentIndex = 0;
timer = new QTimer(this);
timer->setInterval(interval);
connect(timer, SIGNAL(timeout()), this, SLOT(changedAds()));
timer->start();
void AdsWidget::changedAds()
if (names.count() == 0)
return;
if (currentIndex < names.count() - 1)
currentIndex++;
else
currentIndex = 0;
changedAds(labs.at(currentIndex));
void AdsWidget::changedAds(QLabel *lab)
//这里采用样式改变背景颜色的方式,也可以改成贴背景图的方式
QString qss;
QString qssCurrent;
if (bannerStyle == BannerStyle_Min)
qss = "QLabelbackground:#4380A8;";
qssCurrent = "QLabelbackground:#084279;";
else if (bannerStyle == BannerStyle_Num)
qss = "QLabelcolor:#FFFFFF;background:rgba(0,0,0,40);";
qssCurrent = "QLabelcolor:#FFFFFF;background:#0C7FC8;";
//将当前广告指示器突出显示
foreach (QLabel *currentLab, labs)
if (currentLab == lab)
currentLab->setStyleSheet(qssCurrent);
else
currentLab->setStyleSheet(qss);
//更新索引和图片
currentIndex = labs.indexOf(lab);
widgetBg->setStyleSheet(QString("QWidget#widgetBgborder-image:url(%1);").arg(names.at(currentIndex)));
int AdsWidget::getInterval() const
return this->interval;
QSize AdsWidget::getBannerFixedSize() const
return this->bannerFixedSize;
AdsWidget::BannerStyle AdsWidget::getBannerStyle() const
return this->bannerStyle;
QString AdsWidget::getImageNames() const
return this->imageNames;
QSize AdsWidget::sizeHint() const
return QSize(200, 150);
QSize AdsWidget::minimumSizeHint() const
return QSize(20, 15);
void AdsWidget::setInterval(int interval)
if (this->interval != interval)
this->interval = interval;
timer->setInterval(interval);
void AdsWidget::setBannerFixedSize(const QSize &bannerFixedSize)
if (this->bannerFixedSize != bannerFixedSize)
this->bannerFixedSize = bannerFixedSize;
foreach (QLabel *lab, labs)
lab->setFixedSize(bannerFixedSize);
void AdsWidget::setBannerStyle(const AdsWidget::BannerStyle &bannerStyle)
if (this->bannerStyle != bannerStyle)
this->bannerStyle = bannerStyle;
foreach (QLabel *lab, labs)
if (bannerStyle == BannerStyle_Min)
lab->setText("");
else if (bannerStyle == BannerStyle_Num)
lab->setText(lab->text());
void AdsWidget::setImageNames(const QString &imageNames)
if (this->imageNames != imageNames)
this->imageNames = imageNames;
//先清空原有所有指示器
qDeleteAll(labs);
labs.clear();
//根据图片链表自动生成导航指示器和图片链表
names = this->imageNames.split(";");
for (int i = 0; i < names.count(); i++)
QLabel *lab = new QLabel;
widgetBanner->layout()->addWidget(lab);
lab->setFixedSize(bannerFixedSize);
lab->setAlignment(Qt::AlignCenter);
lab->installEventFilter(this);
if (bannerStyle == BannerStyle_Num)
lab->setText(QString::number(i + 1));
labs.append(lab);
//立即显示第一张
changedAds();
六、控件介绍
- 超过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编写自定义控件20-自定义饼图(代码片段)
前言上次在写可视化数据大屏电子看板项目的时候,为了逐步移除对QChart的依赖(主要是因为QChart真的太垃圾了,是所有Qt的模块中源码最烂的一个,看过源码的人没有一个不吐槽,不仅不支持10W级别的数据量曲线展示,居然一... 查看详情
qt编写自定义控件25-自定义qcustomplot(代码片段)
一、前言上次在写大屏数据可视化电子看板系统时候,提到过改造QCustomPlot来实现柱状分组图、横向柱状图、横向分组图、鼠标悬停提示等。这次单独列出来描述,有很多人疑问为啥不用QChart,或者echart等形式,其实这两种方式... 查看详情
qt编写自定义控件:左上角圆形菜单控件(代码片段)
代码:#ifndefROUNDMMENUINUPPERLEFTCORNERWIDGET_H#defineROUNDMMENUINUPPERLEFTCORNERWIDGET_H#include<QWidget>#include<QTimer>#include<QPainterPath>classRoundMmenuInUpperLeftCornerWidget:publicQWidgetQ_OBJECTpublic:RoundMmenuInUpperLeftCornerWidget(QWidget*parent=nullptr);... 查看详情
qt编写自定义控件13-多态进度条(代码片段)
前言多态进度条,顾名思义,有多重状态,其实本控件主要是用来表示百分比进度的,由于之前已经存在了百分比进度条控件,名字被霸占了,按照先来先得原则,只好另外取个别名叫做多态进度条,应用场景是,某种任务有三... 查看详情
qt编写自定义控件22-蚂蚁线(代码片段)
一、前言关于蚂蚁线控件,相信很多用过PS的人都知道,在选中某个区域以后,边上的线条会有一种动态流动的效果,这种效果就叫做蚂蚁线,百科的解释是:动物的一种本能现象,领头的蚂蚁以随机的路线走向食物或洞穴,第... 查看详情
qt编写自定义控件21-圆弧仪表盘(代码片段)
一、前言圆弧仪表盘在整个自定义控件大全中也稍微遇到了技术难点,比如背景透明,如果采用以前画圆形画扇形的方式绘制,肯定很难形成背景透明,需要用到切割,最后换了一种绘制方法,采用绘制圆弧的方式,即使用drawAr... 查看详情
qt编写自定义控件14-环形进度条(代码片段)
前言环形进度条,用来展示当前进度,为了满足大屏UI的需要特意定制,以前有个叫圆环进度条,不能满足项目需要,只能重新定做,以前的进度间距不能自适应分辨率,而且当前进度对应的反的进度不能单独设置颜色,即当前... 查看详情
qt编写自定义控件15-百分比仪表盘(代码片段)
前言百分比仪表盘,主要的应用场景是展示销售完成率、产品合格率等,也可以作为一个进度百分比展示,可以独立设置对应的标题文字,标题文字的颜色和整体的颜色都可以单独设置,建议设置成统一的风格,这样会显得更加... 查看详情
qt自定义控件(代码片段)
一,首先新建一个功能,例如:spprogressbar spprogressbar.proCONFIG+=plugindebug_and_releaseTARGET=$$qtLibraryTarget(spprogressbarplugin)TEMPLATE=libDESTDIR=$$PWD/../libHEADER_PATH=$$PWD/../../includeSOURCE_PATH=$$P 查看详情
qt+自定义控件-spin+slider(代码片段)
动手实现自定义控件:1、首先在ui界面中添加一个(Widget)容器类。如图中的1所示2、在项目中添加一个SmallWidget类,如下: 3、接着在程序编辑界面进行程序编辑如下:#include"smallwidget.h"/*... 查看详情
qt编写自定义控件插件开放动态库dll使用(永久免费)
...想要使用其中一个控件,必须包含所有的代码。全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,不乱码,可直接集成到QtCreator中,和自带的控件一样使用,大部分效果只要设置几个... 查看详情
qt编写自定义控件68-ip地址输入框(代码片段)
一、前言这个IP地址输入框控件,估计写烂了,网上随便一搜索,保证一大堆,估计也是因为这个控件太容易了,非常适合新手练手,一般的思路都是用4个qlineedit控件拼起来,然后每个输入框设置正则表达式过滤只能输入3位数... 查看详情
cyclerotationview:自定义控件之轮播图
CycleRotationView:自定义控件,主要功能是实现类似与各种商城首页的广告轮播图。其实像这种比较常见的自定义控件早就满大街了,虽然说“不要重复发明轮子”,但是不代表不用关心轮子是怎么造的,本着“知其然知其所以然... 查看详情
qt编写自定义控件属性设计器
以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用场景需要自定义绘制一些控件... 查看详情
qt编写自定义控件70-扁平化flatui(代码片段)
一、前言对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反而没有扁平化... 查看详情
qt编写自定义控件5-柱状温度计(代码片段)
前言柱状温度计控件,可能是很多人练手控件之一,基本上都是垂直方向展示,底部一个水银柱,中间刻度尺,刻度尺可以在左侧右侧或者两侧都有,自适应分辨率改动,有时候为了美观效果,可能还会整个定时器来实现动画效... 查看详情
qt编写自定义控件大全
最新版可执行文件 http://pan.baidu.com/s/1i491FQP不定期增加控件及修正BUG和改进算法。总图:1:动画按钮 *1:可设置显示的图像和底部的文字 *2:可设置普通状态图片 *3:可设置进入状态图片 *4:可设置离开状态图片&nbs... 查看详情
qt自定义控件之仪表盘的完整实现(代码片段)
...美工提供的图片的基础上增加动态效果。然而搞明白QT自定义控件的绘图后,这种实现是最简单的。且定制度高,想要什么效果就可以自己绘制个。这里介绍下Qt自定义控件之仪表盘的完整实 查看详情