广告轮播这个控件作的比较早,是很早之前定制一个电信客户端时候用到的,该客户端须要在首页展现轮播预先设定好的图片,图片的路径能够自由设定,而后轮播的间隔速度能够自由控制,同时该控件还须要提供两种指示器的风格,一种是迷你型的样式,一种是数字型的样式。
本控件很早就作好了,因为当时的QPainter功力不足,还不是很熟悉QPainter,采用的是效率比较低的直接用现有控件堆积而成,好比指示器采用的QLabel,用样式表来控制对应的形状,指示器所在的底部放一个widget,采用左右布局,而后右侧放一个弹簧把指示器label所有顶在左边,至于图片的显示,采用的是样式表中的border-image来设置,开个定时器,到了时间则设置成不一样的border-image便可。这种方法虽然效率低了点,可是初学者很容易理解接收,甚至能够作出更多的效果,只要项目对CPU要求不高,也不失为一种还行的办法。程序员
#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 = "QLabel{background:#4380A8;}"; qssCurrent = "QLabel{background:#084279;}"; } else if (bannerStyle == BannerStyle_Num) { qss = "QLabel{color:#FFFFFF;background:rgba(0,0,0,40);}"; qssCurrent = "QLabel{color:#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#widgetBg{border-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(); } }