Qt to write custom ad rotation controls 23-

I. Introduction

Ad rotation controls to do this earlier, is a long time ago, when a custom end telecom customers used, the client needs to show on the home page carousel predefined images, the image path can be freely set, then round broadcast interval speed can be freely controlled, while the control indicator also need to provide two styles, one is a mini-style, one is digital type style.
This control is done very early, due to lack of time QPainter skill, not very familiar with QPainter, uses a relatively low efficiency of existing controls directly deposited by, for example QLabel indicator used by style sheets to control a shape corresponding to a place where the bottom indicator widget, using about the layout, and a spring put right indicator label all the top on the left, as the display images, using the border-image to set style sheet, open timer, the time is set to a different border-image can. Although this method is inefficient point, but it is easy to understand for beginners reception, and even make more effect, as long as the project less demanding on the CPU, may well be an okay way.

Second, the realization of functions

  • 1: the image display can be provided
  • 2: You can add more ads
  • 3: You can set the style mini style digital indicator type style
  • 4: the size indicator may be provided
  • 5: the switching interval may be provided

Third, renderings



Fourth, the header file code

#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

Five complete code

#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();
    }
}


Sixth, the controls described

  1. More than 146 exquisite control, covers a variety of dashboards, progress bar, the progress of the ball, compass, graphs, scales, thermometers, navigation bar, navigation bar, flatui, highlight the button, slide the selector, the lunar calendar and so on. Qwt far more than the number of controls integration.
  2. Each class can be independently as a separate control, zero coupling each control file and a header file to achieve a code amount, independent of other files to facilitate individual control integrated into the project source code form, less. qwt interlocking control class, highly coupled, want to use one of the controls, must contain all the code.
  3. Write all pure Qt, QWidget + QPainter to draw, to support any Qt version Qt4.6 Qt5.12, support for mingw, msvc, gcc compiler, etc., not garbled, can be integrated directly into the Qt Creator, and comes with the same controls use, most of the effects can be as long as several properties are set, very convenient.
  4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
  5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
  6. 每个控件默认配色和demo对应的配色都非常精美。
  7. 超过130个可见控件,6个不可见控件。
  8. 部分控件提供多种样式风格选择,多种指示器样式选择。
  9. 所有控件自适应窗体拉伸变化。
  10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
  11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
  12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
  13. 所有控件最后生成一个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、学习方法、写作技巧、热门技术、职场发展等内容,干货多多,福利多多!

Guess you like

Origin www.cnblogs.com/feiyangqingyun/p/10987726.html