廣告輪播這個控件作的比較早,是很早之前定製一個電信客戶端時候用到的,該客戶端須要在首頁展現輪播預先設定好的圖片,圖片的路徑能夠自由設定,而後輪播的間隔速度能夠自由控制,同時該控件還須要提供兩種指示器的風格,一種是迷你型的樣式,一種是數字型的樣式。
本控件很早就作好了,因爲當時的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(); } }