Qt to write custom controls 24- Image Carousel control

I. Introduction

An article written by ad rotation controls, the use of traditional widget set style sheets piled to do, this time must be used to more advanced QPainter to draw, this is the most efficient way to reference the controls Amada brother carousel controls, has undergone extensive renovation made compared to the original ad rotation controls, the controls can be finished blasting him by rubbing hard on the ground. In addition to setting the picture path set, it also can set the message corresponding to the most common in many web carousel image effects, such as news title, etc., can be more intuitive display the current picture, and click on the picture can also support jump, the position indicator can also be provided on the right + left + center indicator stripe of the pattern is more increased elliptical + circular dot + + + rectangular elongated variety Alternatively, it can be said to cover a variety of the effect of web carousel of pictures, you can also set the hover pause carousel to see the carousel continues to explain the mouse away. Color indicator width and height, are set free, using for this QPainter drawing, it is best custom canvas QBrush nothing more than setting the color and the corresponding brush QPen corresponding to it.

Second, the realization of functions

  • 1: You can set the image path set
  • 2: You can set message collection
  • 3: the indicator can be set minimum and maximum widths
  • 4: Image switching interval may be provided
  • 5: You can set the indicator color and text color tips
  • 6: the height indicator can be set
  • 7: Reference display indicator may be provided
  • 8: a position indicator may be provided on the right + left + center
  • 9: the indicator can be set elliptical strip style rectangular + + + round dot elongated +
  • 10: You can set Hover stop carousel

Third, renderings

Fourth, the header file code

#ifndef ADSWIDGET2_H
#define ADSWIDGET2_H

/**
 * 广告轮播控件2 作者:feiyangqingyun(QQ:517216493) 2018-9-12
 * 参考雨田哥(QQ:3246214072) https://blog.csdn.net/ly305750665/article/details/82496046
 * 1:可设置图片路径集合
 * 2:可设置提示信息集合
 * 3:可设置指示器最小宽度和最大宽度
 * 4:可设置图片切换间隔
 * 5:可设置指示器颜色和提示文字颜色
 * 6:可设置指示器高度
 * 7:可设置指示器显示序号
 * 8:可设置指示器位置 左边+中间+右边
 * 9:可设置指示器的样式 椭圆条状+圆形+矩形+小圆点+长条状
 * 10:可设置鼠标悬停停止轮播
 */

#include <QWidget>

class QLabel;
class QHBoxLayout;
class QSpacerItem;
class QParallelAnimationGroup;
class QPropertyAnimation;

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT AdsWidget2 : public QWidget
#else
class AdsWidget2 : public QWidget
#endif

{
    Q_OBJECT
    Q_ENUMS(NavPosition)
    Q_ENUMS(NavStyle)

    Q_PROPERTY(bool hoverStop READ getHoverStop WRITE setHoverStop)
    Q_PROPERTY(bool showNumber READ getShowNumber WRITE setShowNumber)

    Q_PROPERTY(int minHeight READ getMinHeight WRITE setMinHeight)
    Q_PROPERTY(int minWidth READ getMinWidth WRITE setMinWidth)
    Q_PROPERTY(int maxWidth READ getMaxWidth WRITE setMaxWidth)
    Q_PROPERTY(int interval READ getInterval WRITE setInterval)
    Q_PROPERTY(int navRadius READ getNavRadius WRITE setNavRadius)

    Q_PROPERTY(QColor navColor READ getNavColor WRITE setNavColor)
    Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
    Q_PROPERTY(QColor tipColor READ getTipColor WRITE setTipColor)
    Q_PROPERTY(QColor darkColor READ getDarkColor WRITE setDarkColor)

    Q_PROPERTY(QString imageNames READ getImageNames WRITE setImageNames)
    Q_PROPERTY(QString imageTips READ getImageTips WRITE setImageTips)

    Q_PROPERTY(NavPosition navPosition READ getNavPosition WRITE setNavPosition)
    Q_PROPERTY(NavStyle navStyle READ getNavStyle WRITE setNavStyle)

public:
    enum NavPosition {
        NavPosition_Left = 0,       //左边位置
        NavPosition_Center = 1,     //中间位置
        NavPosition_Right = 2       //右侧位置
    };

    enum NavStyle {
        NavStyle_Ellipse = 0,       //椭圆条状
        NavStyle_Circle = 1,        //圆形
        NavStyle_Rect = 2,          //矩形
        NavStyle_Dot = 3,           //小圆点
        NavStyle_LongRect = 4       //长条状
    };

    AdsWidget2(QWidget *parent = 0);
    ~AdsWidget2();

protected:
    bool eventFilter(QObject *obj, QEvent *event);
    void enterEvent(QEvent *);
    void leaveEvent(QEvent *);
    void showEvent(QShowEvent *);
    void paintEvent(QPaintEvent *);

private:
    bool hoverStop;         //鼠标悬停停止轮播
    bool showNumber;        //是否显示序号

    int minHeight;          //指示器最小高度
    int minWidth;           //指示器最小拉伸宽度
    int maxWidth;           //指示器最大拉伸宽度
    int interval;           //图片切换间隔,单位毫秒
    int navRadius;          //指示器圆角角度

    QColor navColor;        //指示器颜色
    QColor textColor;       //指示器文字颜色
    QColor tipColor;        //提示文字颜色
    QColor darkColor;       //当前指示器加深颜色

    QString imageNames;     //图片名称
    QString imageTips;      //提示信息

    NavPosition navPosition;//指示器位置
    NavStyle navStyle;      //指示器样式

    QList<QString> names;   //图片名称集合
    QList<QString> tips;    //提示信息集合
    QList<QLabel *> labs;   //存储指示器集合

    bool leftToRight;       //从左往右切换
    int offset;             //图片切换偏移量
    int currentIndex;       //当前图片索引
    int previousIndex;      //上一张图片索引

    QString qssNormal;      //正常状态样式
    QString qssCurrent;     //当前状态样式

    QTimer *timer;          //定时器切换
    QHBoxLayout *layout;    //指示器所在布局
    QSpacerItem *spacerLeft;//左侧弹簧
    QSpacerItem *spacerRight;//右侧弹簧
    QWidget *widgetNav;     //存放导航指示器的容器

    //动画切换
    QParallelAnimationGroup *animationGroup;
    QPropertyAnimation *animationImage;
    QPropertyAnimation *animationMin;
    QPropertyAnimation *animationMax;

private slots:
    void initWidget();
    void initForm();
    void initQss();
    void changedAds();
    void changedAds(QLabel *lab);
    void changedImage(const QVariant &);
    void changedMin(const QVariant &);
    void changedMax(const QVariant &);

public:
    bool getHoverStop()         const;
    bool getShowNumber()        const;

    int getMinHeight()          const;
    int getMinWidth()           const;
    int getMaxWidth()           const;
    int getInterval()           const;
    int getNavRadius()          const;

    QColor getNavColor()        const;
    QColor getTextColor()       const;
    QColor getTipColor()        const;
    QColor getDarkColor()       const;

    QString getImageNames()     const;
    QString getImageTips()      const;

    NavPosition getNavPosition()const;
    NavStyle getNavStyle()      const;

    QSize sizeHint()            const;
    QSize minimumSizeHint()     const;

public Q_SLOTS:
    //设置鼠标悬停停止轮播
    void setHoverStop(bool hoverStop);
    //设置是否显示序号
    void setShowNumber(bool showNumber);

    //设置指示器高度
    void setMinHeight(int minHeight);
    //设置最小拉伸宽度
    void setMinWidth(int minWidth);
    //设置最大拉伸宽度
    void setMaxWidth(int maxWidth);
    //设置切换间隔
    void setInterval(int interval);
    //设置指示器圆角角度
    void setNavRadius(int navRadius);

    //设置指示器颜色
    void setNavColor(const QColor &navColor);
    //设置指示器文字颜色
    void setTextColor(const QColor &textColor);
    //设置提示信息颜色
    void setTipColor(const QColor &tipColor);
    //设置加深颜色
    void setDarkColor(const QColor &darkColor);

    //设置图片名称
    void setImageNames(const QString &imageNames);
    //设置提示信息
    void setImageTips(const QString &imageTips);

    //设置指示器位置
    void setNavPosition(const NavPosition &navPosition);
    //设置指示器样式
    void setNavStyle(const NavStyle &navStyle);
};

#endif // ADSWIDGET2_H

Fifth, the core code

void AdsWidget2::paintEvent(QPaintEvent *)
{
    if (names.count() == 0) {
        return;
    }

    int width = this->width();
    int height = this->height();

    QPainter painter(this);
    painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
    QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);
    painter.setPen(tipColor);

    //设置字体
    QFont font;
    font.setPixelSize(15);
    painter.setFont(font);

    //取出上一张图片+当前图片,并平滑缩放
    QPixmap previousPix(names.at(previousIndex));
    QPixmap currentPix(names.at(currentIndex));
    previousPix = previousPix.scaled(width, height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
    currentPix = currentPix.scaled(width, height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);

    int widthOffset = offset + width;
    if (leftToRight) {
        widthOffset = offset - width;
    }

    //绘制上一张图片
    painter.drawPixmap(offset, 0, previousPix);
    //绘制当前图片
    painter.drawPixmap(widthOffset, 0, currentPix);

    //绘制上一张图片提示信息,有可能上一张图片提示信息为空
    if (previousIndex <= tips.count() - 1) {
        painter.drawText(QRect(offset + 10, height - minHeight - 40, width - 20, 30), tips.at(previousIndex), option);
    }

    //绘制当前图片提示信息,有可能当前图片提示信息为空
    if (currentIndex <= tips.count() - 1) {
        painter.drawText(QRect(widthOffset + 10, height - minHeight - 40, width - 20, 30), tips.at(currentIndex), option);
    }
}

void AdsWidget2::initWidget()
{
    //放置指示器的窗体载体
    widgetNav = new QWidget(this);
    widgetNav->setObjectName(QString::fromUtf8("widgetNav"));

    //给指示器窗体加上左右布局
    layout = new QHBoxLayout(widgetNav);
    layout->setSpacing(3);

    //主布局,上下布局
    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    verticalLayout->setSpacing(0);
    verticalLayout->setContentsMargins(0, 0, 0, 0);

    //上部弹簧,用于将指示器区域弹到底部
    QSpacerItem *verticalSpacer = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding);
    verticalLayout->addItem(verticalSpacer);

    //将指示器窗体加入到主布局中下部
    verticalLayout->addWidget(widgetNav);

    //实例化左侧右侧弹簧
    spacerLeft = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
    spacerRight = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
}

void AdsWidget2::initForm()
{
    hoverStop = true;
    showNumber = false;

    minHeight = 6;
    minWidth = 6;
    maxWidth = 25;
    interval = 3000;
    navRadius = 3;

    navColor = QColor(220, 220, 220);
    textColor = QColor(20, 20, 20);
    tipColor = QColor(255, 255, 255);
    darkColor = QColor(255, 255, 255);

    imageNames.clear();
    imageTips.clear();

    navPosition = NavPosition_Left;
    navStyle = NavStyle_Ellipse;

    leftToRight = true;
    offset = 0;
    currentIndex = 0;
    previousIndex = 0;

    //定时器切换图片
    timer = new QTimer(this);
    timer->setInterval(interval);
    connect(timer, SIGNAL(timeout()), this, SLOT(changedAds()));

    this->setMouseTracking(true);

    //定义动画组
    animationGroup = new QParallelAnimationGroup(this);

    //定义动画切换图片
    animationImage = new QPropertyAnimation(this, "");
    connect(animationImage, SIGNAL(valueChanged(const QVariant &)), this, SLOT(changedImage(const QVariant &)));
    animationImage->setEasingCurve(QEasingCurve::OutCirc);
    animationImage->setDuration(1000);
    animationGroup->addAnimation(animationImage);

    QSequentialAnimationGroup *sequentialGroup = new QSequentialAnimationGroup(animationGroup);

    //用于切换最小拉伸宽度
    animationMin = new QPropertyAnimation(sequentialGroup, "");
    connect(animationMin, SIGNAL(valueChanged(const QVariant &)), this, SLOT(changedMin(const QVariant &)));
    animationMin->setEasingCurve(QEasingCurve::OutCubic);
    animationMin->setDuration(500);

    //用于切换最大拉伸宽度
    animationMax = new QPropertyAnimation(sequentialGroup, "");
    connect(animationMax, SIGNAL(valueChanged(const QVariant &)), this, SLOT(changedMax(const QVariant &)));
    animationMax->setEasingCurve(QEasingCurve::OutCubic);
    animationMax->setDuration(500);

    //按钮切换串行运行
    sequentialGroup->addAnimation(animationMin);
    sequentialGroup->addAnimation(animationMax);
    animationGroup->addAnimation(sequentialGroup);
}

void AdsWidget2::initQss()
{
    //可自行拓展自定义样式
    if (navStyle == NavStyle_Dot) {
        qssNormal = QString("border:none;background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,"
                            "stop:0 #00FFFFFF,stop:0.4 #00FFFFFF,"
                            "stop:0.5 #00FFFFFF,stop:0.6 #00FFFFFF,stop:0.7 rgba(%1,%2,%3,%4));"
                            "color:rgba(%5,%6,%7,%8);border-radius:%9px;")
                    .arg(navColor.red()).arg(navColor.green()).arg(navColor.blue()).arg(navColor.alpha())
                    .arg(textColor.red()).arg(textColor.green()).arg(textColor.blue()).arg(navColor.alpha()).arg(navRadius);
        qssCurrent = QString("border:none;background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,"
                             "stop:0 rgba(%1,%2,%3,%4),stop:0.4 rgba(%1,%2,%3,%4),"
                             "stop:0.5 #00FFFFFF,stop:0.6 #00FFFFFF,stop:0.7 rgba(%1,%2,%3,%4));"
                             "color:rgba(%5,%6,%7,%8);border-radius:%9px;")
                     .arg(darkColor.red()).arg(darkColor.green()).arg(darkColor.blue()).arg(darkColor.alpha())
                     .arg(textColor.red()).arg(textColor.green()).arg(textColor.blue()).arg(navColor.alpha()).arg(navRadius);

    } else {
        qssNormal = QString("border:none;background:rgba(%1,%2,%3,%4);color:rgba(%5,%6,%7,%8);border-radius:%9px;")
                    .arg(navColor.red()).arg(navColor.green()).arg(navColor.blue()).arg(navColor.alpha())
                    .arg(textColor.red()).arg(textColor.green()).arg(textColor.blue()).arg(navColor.alpha()).arg(navRadius);
        qssCurrent = QString("border:none;background:rgba(%1,%2,%3,%4);color:rgba(%5,%6,%7,%8);border-radius:%9px;")
                     .arg(darkColor.red()).arg(darkColor.green()).arg(darkColor.blue()).arg(darkColor.alpha())
                     .arg(textColor.red()).arg(textColor.green()).arg(textColor.blue()).arg(textColor.alpha()).arg(navRadius);
    }
}

void AdsWidget2::changedAds()
{
    if (names.count() == 0) {
        return;
    }

    previousIndex = currentIndex;
    if (currentIndex < names.count() - 1) {
        currentIndex++;
    } else {
        currentIndex = 0;
    }

    changedAds(labs.at(currentIndex));
}

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., support any operating system such as windows + linux + mac + embedded linux, which does not garbled can be directly integrated into Qt Creator, a built-in controls and use the same, most of the effects can be as long as several properties are set, very convenient.
  4. DEMO separate source containing the control corresponding to each control has a convenient reference. It also provides integrated use of all controls a DEMO.
  5. Source code for each control has detailed Chinese annotation, are prepared in accordance with unified design specifications, easy to learn to write custom controls.
  6. Each control default color and demo corresponding color is very beautiful.
  7. More than 130 visible control, six invisible control.
  8. Portion control provides a variety of styles style selection, multiple choice style indicator.
  9. All controls changes adaptive stretched form.
  10. Integrated design custom attribute that supports drag design, WYSIWYG support the import and export in xml format.
  11. Activex control that comes with demo, all controls can be run directly in the browser ie.
  12. Fontawesome integrated graphics font + Alibaba iconfont collection of hundreds of graphic fonts, font fun graphic brings.
  13. All controls and finally generate a dll dynamic library files, can be integrated directly into qtcreator designed for use in drag.

Seven, SDK download

  • SDK download link: https://pan.baidu.com/s/1tD9v1YPfE2fgYoK6lqUr1Q extraction code: lyhk
  • + Custom attributes Designer appreciation: https://pan.baidu.com/s/1l6L3rKSiLu_uYi7lnL3ibQ extraction code: tmvl
  • Download link is included in the various versions of the dynamic library files, header files of all the controls, the use of demo.
  • Open plug-in custom dynamic library dll use (permanent free), and the back door without any restrictions, ease of use.
  • 26 now available version dll, which includes qt5.12.3 msvc2017 32 + 64 mingw 32 + 64 in.
  • From time to time to increase control and improve controls, regularly updated SDK, to welcome all suggestions, thank you!
  • widget versions (QQ: 517216493) qml versions (QQ: 373955953) sambong camel (QQ: 278969898).
  • Qt's advanced column know almost Taoge road https://zhuanlan.zhihu.com/TaoQt
  • Welcome concern public micro-channel number] [efficient programmers, content C ++ / Python, learning, writing skills, popular technology, career development, a lot of dry goods, benefits a lot!

Guess you like

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