基本信息
源码名称:Qt 广告轮播图仿写
源码大小:2.03M
文件格式:.zip
开发语言:C/C++
更新时间:2020-12-03
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
Qt轮播图实现,在一个机会下,面试官让我写一个Qt轮播图功能的项目,所以我就把它传到这供大家参考,我认为功能还是比较全的,笔者把一些功能都是写活的,并且有非常详实的注释,比较适合初学者对信号槽机制的掌握,也方便大家使用。我个人认为Qt的轮播图确实很考验一个开发者使用信号槽机制的使用情况。
里面的注释也写的挺全的,希望对大家有所帮助~~
/* * LKYSlidesShow轮播 1.0 * L·K`Y * 2020.11.13 02:33 * Cheer Up!!! */ #include "lkyslidesshow.h" #include <QLayoutItem> #include <QVBoxLayout> #include <QHBoxLayout> #include <QMessageBox> #include <QDebug> LKYSlidesShow::LKYSlidesShow(QWidget *parent) : QWidget(parent) { m_turnLeft = true; //轮播方向 m_navTextVisible = false; //显示导航器序号 m_mouseHoverStop = false; //是否鼠标悬停 m_mouseNavHoverChange = false; //是否鼠标悬停导航器按钮时图片切换 m_navType = Rectangle; //导航器样式 m_navPos = Left; //导航器位置 m_navBtnSize = QSize(30, 24); //导航器按钮大小 m_navTextColor = Qt::black; //导航器序号颜色 m_navColor = QColor(128, 128, 128); //导航器颜色 m_navHoverColor = Qt::yellow; //导航器悬停颜色 m_navPressColor = Qt::green; //导航器按下颜色 m_curIndex = 0; //当前图片索引 m_preIndex = 0; //之前图片索引 m_offsetX = 0; //图片偏移量 m_changePixmapInterVal = 3000; //图片切换间隔(图片轮换间隔,包含了图片动画间隔,单位:毫秒) m_PixmapAnimationInterval = 1000; //图片移动间隔(图片动画间隔,单位:毫秒) initForm(); //初始化定时器 m_timer = new QTimer(this); m_timer->setInterval(m_changePixmapInterVal); connect(m_timer,SIGNAL(timeout()),this,SLOT(onTimeout())); //初始化动画 m_animation = new QPropertyAnimation(this, "offsetX"); m_animation->setDuration(m_PixmapAnimationInterval); this->setMouseTracking(true); this->setAttribute(Qt::WA_Hover, true); } void LKYSlidesShow::setPixmapAnimationInterval(int msecs) { m_PixmapAnimationInterval = msecs; } void LKYSlidesShow::setPlayDir(bool turnLeft) { m_turnLeft = turnLeft; } void LKYSlidesShow::setPixmap(const QList<QPixmap *> &pixmaps) { //停止定时器、停止动画 if (m_timer->isActive()) m_timer->stop(); if (m_animation->state() == QAbstractAnimation::Running) m_animation->stop(); //清空数据 qDeleteAll(m_pixmaps); m_pixmaps.clear(); m_btns.clear(); //清空布局中的数据 QLayoutItem *child; while ((child = m_hNavLayout->takeAt(0)) != nullptr) { QWidget *widget = child->widget(); delete widget; delete child; } //赋值数据 m_pixmaps = pixmaps; for(int i = 0; i < pixmaps.count(); i ) { QPushButton *btn = new QPushButton(QString::number(i 1)); btn->setFixedWidth(30); m_hNavLayout->addWidget(btn); m_btns.append(btn); connect(btn,SIGNAL(clicked()), this, SLOT(onClicked())); btn->installEventFilter(this); } m_curIndex = m_preIndex = 0; setNavType(m_navType); setNavPos(m_navPos); m_timer->start(); //图片切换时,发送图片索引 emit currentIndexChange(m_curIndex); update(); } void LKYSlidesShow::setNavType(NavType navType) { m_navType = navType; for (int i = 0; i < m_btns.count(); i ) { QString qss = ""; QPushButton *btn = m_btns.at(i); //控制导航器序号显示与否 if (m_navTextVisible) btn->setText(QString::number(i 1)); else btn->setText(""); //控制导航器样式 if (navType == Rectangle) { btn->setFixedSize(m_navBtnSize); if (i == m_curIndex) { qss = QString("QPushButton{border:none; background-color:rgb(%1, %2, %3); color:rgb(%4, %5, %6);}\ QPushButton:hover{border:none; background-color:rgb(%7, %8, %9); color:rgb(%4, %5, %6)}\ QPushButton:pressed{border:none; background-color:rgb(%1, %, %3); color:rgb(%4, %5, %6)}") .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()); } else { qss = QString("QPushButton{border:none; background-color:rgb(%1, %2, %3); color:rgb(%4, %5, %6);}\ QPushButton:hover{border:none; background-color:rgb(%7, %8, %9); color:rgb(%4, %5, %6)}\ QPushButton:pressed{border:none; background-color:rgb(%10, %11, %12); color:rgb(%4, %5, %6)}") .arg(m_navColor.red()).arg(m_navColor.green()).arg(m_navColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()); } } else if (navType == RoundedRectangle) { btn->setFixedSize(m_navBtnSize); if (i == m_curIndex) { qss = QString("QPushButton{border:none; border-radius:5px; background-color:rgb(%1, %2, %3); color:rgb(%4, %5, %6);}\ QPushButton:hover{border:none; background-color:rgb(%7, %8, %9); color:rgb(%4, %5, %6)}\ QPushButton:pressed{border:none; background-color:rgb(%1, %, %3); color:rgb(%4, %5, %6)}") .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()); } else { qss = QString("QPushButton{border:none; border-radius:5px; background-color:rgb(%1, %2, %3); color:rgb(%4, %5, %6);}\ QPushButton:hover{border:none; background-color:rgb(%7, %8, %9); color:rgb(%4, %5, %6)}\ QPushButton:pressed{border:none; background-color:rgb(%10, %11, %12); color:rgb(%4, %5, %6)}") .arg(m_navColor.red()).arg(m_navColor.green()).arg(m_navColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()); } } else if (navType == Circle) { //将用户设定的导航器按钮设置为正方形,用于设置样式为正圆 int len = qMin(m_navBtnSize.width(), m_navBtnSize.height()); len = len % 2 == 0 ? len : len 1; btn->setFixedSize(len ,len); if (i == m_curIndex) { qss = QString("QPushButton{border:none; border-radius:%1px; background-color:rgb(%2, %3, %4); color:rgb(%5, %6, %7);}\ QPushButton:hover{border:none; background-color:rgb(%8, %9, %10); color:rgb(%5, %6, %7)}\ QPushButton:pressed{border:none; background-color:rgb(%2, %3, %4); color:rgb(%5, %6, %7)}") .arg(len / 2) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()); } else { qss = QString("QPushButton{border:none; border-radius:%1px; background-color:rgb(%2, %3, %4); color:rgb(%5, %6, %7);}\ QPushButton:hover{border:none; border-radius:%1px; background-color:rgb(%8, %9, %10); color:rgb(%5, %6, %7)}\ QPushButton:pressed{border:none; border-radius:%1px; background-color:rgb(%11, %12, %13); color:rgb(%5, %6, %7)}") .arg(len / 2) .arg(m_navColor.red()).arg(m_navColor.green()).arg(m_navColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()); } } else if (navType == ConCentric_circle) { //将用户设定的导航器按钮设置为正方形,用于设置样式为正圆 int len = qMin(m_navBtnSize.width(), m_navBtnSize.height()); len = len % 2 == 0 ? len : len 1; btn->setFixedSize(len, len); if (i == m_curIndex) { qss = QString("QPushButton{border:none; border-radius:%1px; background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(%2, %3, %4), stop:0.4 rgb(%2, %3, %4), stop:0.6 transparent, stop:1 rgb(%2, %3, %4)); color:rgb(%5, %6, %7);}\ QPushButton:hover{border:none; background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(%8, %9, %10), stop:0.4 rgb(%8, %9, %10), stop:0.6 transparent, stop:1 rgbrgb(%8, %9, %10)); color:rgb(%5, %6, %7)}\ QPushButton:pressed{border:none; background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(%2, %3, %4), stop:0.4 rgb(%2, %3, %4), stop:0.6 transparent, stop:1 rgb(%2, %3, %4)); color:rgb(%5, %6, %7)}") .arg(len / 2) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()); } else { qss = QString("QPushButton{border:none; border-radius:%1px; background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(%2, %3, %4), stop:0.4 rgb(%2, %3, %4), stop:0.6 transparent, stop:1 rgb(%2, %3, %4)); color:rgb(%5, %6, %7);}\ QPushButton:hover{border:none; background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(%8, %9, %10), stop:0.4 rgb(%8, %9, %10), stop:0.6 transparent, stop:1 rgbrgb(%8, %9, %10)); color:rgb(%5, %6, %7)}\ QPushButton:pressed{border:none; background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(%11, %12, %13), stop:0.4 rgb(%11, %12, %13), stop:0.6 transparent, stop:1 rgb(%11, %12, %13)); color:rgb(%5, %6, %7)}") .arg(len / 2) .arg(m_navColor.red()).arg(m_navColor.green()).arg(m_navColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()); } } else if (navType == Ellipse) { btn->setFixedSize(m_navBtnSize); if (i == m_curIndex) { qss = QString("QPushButton{border:none; border-radius:%1px %2px; background-color:rgb(%3, %4, %5); color:rgb(%6, %7, %8);}\ QPushButton:hover{border:none; border-radius:%1px %2px; background-color:rgb(%9, %10, %11); color:rgb(%6, %7, %8)}\ QPushButton:pressed{border:none; border-radius:%1px %2px; background-color:rgb(%3, %4, %5); color:rgb(%6, %7, %8)}") .arg(m_navBtnSize.width() / 2).arg(m_navBtnSize.height() / 2) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()); } else { qss = QString("QPushButton{border:none; border-radius:%1px %2px; background-color:rgb(%3, %4, %5); color:rgb(%6, %7, %8);}\ QPushButton:hover{border:none; border-radius:%1px %2px; background-color:rgb(%9, %10, %11); color:rgb(%6, %7, %8)}\ QPushButton:pressed{border:none; border-radius:%1px %2px; background-color:rgb(%12, %13, %14); color:rgb(%6, %7, %8)}") .arg(m_navBtnSize.width() / 2).arg(m_navBtnSize.height() / 2) .arg(m_navColor.red()).arg(m_navColor.green()).arg(m_navColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()); } } else if (m_navType == AnimationEllipse) { if (i == m_curIndex) { btn->setFixedSize(m_navBtnSize.width() * 2, m_navBtnSize.height()); qss = QString("QPushButton{border:none; border-radius:%1px %2px; background-color:rgb(%3, %4, %5); color:rgb(%6, %7, %8);}\ QPushButton:hover{border:none; border-radius:%1px %2px; background-color:rgb(%9, %10, %11); color:rgb(%6, %7, %8)}\ QPushButton:pressed{border:none; border-radius:%1px %2px; background-color:rgb(%3, %4, %5); color:rgb(%6, %7, %8)}") .arg(m_navBtnSize.width() / 2).arg(m_navBtnSize.height() / 2) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()); } else { btn->setFixedSize(m_navBtnSize); qss = QString("QPushButton{border:none; border-radius:%1px %2px; background-color:rgb(%3, %4, %5); color:rgb(%6, %7, %8);}\ QPushButton:hover{border:none; border-radius:%1px %2px; background-color:rgb(%9, %10, %11); color:rgb(%6, %7, %8)}\ QPushButton:pressed{border:none; border-radius:%1px %2px; background-color:rgb(%12, %13, %14); color:rgb(%6, %7, %8)}") .arg(m_navBtnSize.width() / 2).arg(m_navBtnSize.height() / 2) .arg(m_navColor.red()).arg(m_navColor.green()).arg(m_navColor.blue()) .arg(m_navTextColor.red()).arg(m_navTextColor.green()).arg(m_navTextColor.blue()) .arg(m_navHoverColor.red()).arg(m_navHoverColor.green()).arg(m_navHoverColor.blue()) .arg(m_navPressColor.red()).arg(m_navPressColor.green()).arg(m_navPressColor.blue()); } } btn->setStyleSheet(qss); } } void LKYSlidesShow::setNavPos(LKYSlidesShow::NavPos navPos) { m_navPos = navPos; if (navPos == Left) { m_hLayout->setStretch(0, 0); m_hLayout->setStretch(1, 1); m_hLayout->setStretch(2, 6); } else if (navPos == Center) { m_hLayout->setStretch(0, 3); m_hLayout->setStretch(1, 1); m_hLayout->setStretch(2, 3); } else if(navPos == Right) { m_hLayout->setStretch(0, 6); m_hLayout->setStretch(1, 1); m_hLayout->setStretch(2, 0); } } void LKYSlidesShow::setNavTextVisible(bool textVisible) { m_navTextVisible = textVisible; setNavType(m_navType); } void LKYSlidesShow::setMouseNavHoverChange(bool mouseNavHoverChange) { m_mouseNavHoverChange = mouseNavHoverChange; } void LKYSlidesShow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); //判断是否有图片载入 if(m_pixmaps.count() <= 0) { m_timer->stop(); return; } int width = this->width(); int height = this->height(); QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); if (m_turnLeft) { //向左轮播 QRect preRect = QRect(-m_offsetX, 0, width, height); QRect curRect = QRect(width - m_offsetX, 0, width, height); painter.drawPixmap(preRect, *(m_pixmaps.at(m_preIndex))); painter.drawPixmap(curRect, *(m_pixmaps.at(m_curIndex))); } else { //向右轮播 QRect preRect = QRect(m_offsetX, 0, width, height); QRect curRect = QRect(-width m_offsetX, 0, width, height); painter.drawPixmap(preRect, *(m_pixmaps.at(m_preIndex))); painter.drawPixmap(curRect, *(m_pixmaps.at(m_curIndex))); } } bool LKYSlidesShow::eventFilter(QObject *obj, QEvent *ev) { if (obj->metaObject()->className() == QStringLiteral("QPushButton")) { if(ev->type() == QEvent::HoverEnter) { if(m_mouseNavHoverChange) { if(m_timer->isActive()) m_timer->stop(); m_preIndex = m_curIndex; m_curIndex = m_btns.indexOf((QPushButton *)obj); setNavType(m_navType); m_animation->setStartValue(0); m_animation->setEndValue(width()); //图片切换时,发送图片索引 emit currentIndexChange(m_curIndex); update(); } } else if (ev->type() == QEvent::HoverLeave) { if (!m_timer->isActive() || !m_mouseHoverStop) m_timer->start(); } } return false; } void LKYSlidesShow::initForm() { //导航窗体内部布局 m_navWidget = new QWidget(this); m_hNavLayout = new QHBoxLayout(m_navWidget); m_hNavLayout->setSpacing(2); m_hNavLayout->setMargin(0); m_navWidget->setLayout(m_hNavLayout); //页面底部导航器整体布局 m_hLayout = new QHBoxLayout(); m_lSpacerItem = new QSpacerItem(10, 10, QSizePolicy::Expanding,QSizePolicy::Minimum); m_rSpacerItem = new QSpacerItem(10, 10, QSizePolicy::Expanding,QSizePolicy::Minimum); m_hLayout->addItem(m_lSpacerItem); m_hLayout->addWidget(m_navWidget); m_hLayout->addItem(m_rSpacerItem); m_hLayout->setStretch(0, 3); m_hLayout->setStretch(1, 1); m_hLayout->setStretch(2, 3); m_hLayout->setSpacing(3); m_hLayout->setMargin(0); //图片页整体布局 QVBoxLayout *vLayout = new QVBoxLayout(this); m_vSpacerItem = new QSpacerItem(10, 100, QSizePolicy::Minimum, QSizePolicy::Expanding); vLayout->addItem(m_vSpacerItem); vLayout->addLayout(m_hLayout); vLayout->setStretch(0, 6); vLayout->setStretch(1, 1); vLayout->setSpacing(0); vLayout->setMargin(0); this->setLayout(vLayout); } void LKYSlidesShow::setOffsetX(int offsetX) { m_offsetX = offsetX; if (m_navType == AnimationEllipse) { for (int i = 0;i < m_btns.count();i ) { if(i == m_curIndex) { m_btns.at(i)->setFixedWidth(m_navBtnSize.width() * (1 offsetX * 1.0 / width())); } else { m_btns.at(i)->setFixedSize(m_navBtnSize); } } } update(); } int LKYSlidesShow::getOffsetX() const { return m_offsetX; } void LKYSlidesShow::on_Click_Piece() { if(m_pixmaps.count() == 0) { QMessageBox::critical(NULL, "hinit", "Please select the picture file first", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); return; } m_curIndex--; if(m_curIndex < 0) { m_curIndex = m_pixmaps.count()-1; } setNavType(m_navType); //重新开启定时器 m_timer->start(); m_turnLeft = false; emit currentIndexChange(m_curIndex); update(); } void LKYSlidesShow::onClicked() { if(!m_mouseNavHoverChange) { //点击相应按钮,从当前点击按钮图片开始继续轮播 QPushButton *btn = dynamic_cast<QPushButton *>(sender()); if(btn != nullptr) { int index = m_btns.indexOf(btn); m_curIndex = m_preIndex = index; m_offsetX = 0; //停止定时器及动画,防止刚点击新的图片时,由于之前的定时器快到了,直接触发到下一张图片 m_timer->stop(); m_animation->stop(); setNavType(m_navType); if(!m_mouseHoverStop) { //重新开启定时器 m_timer->start(); } //图片切换时,发送图片索引 emit currentIndexChange(m_curIndex); update(); } } } void LKYSlidesShow::on_Click_Next() { if(m_pixmaps.count() == 0) { QMessageBox::critical(NULL, "hinit", "Please select the picture file first", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); return; } m_curIndex ; //从第一张调到最后一张 if(m_curIndex > m_pixmaps.count()-1) { m_curIndex = 0; } setNavType(m_navType); m_timer->start(); m_turnLeft = true; emit currentIndexChange(m_curIndex); update(); } void LKYSlidesShow::onTimeout() { m_preIndex = m_curIndex; m_curIndex ; //到最后一张Index再重新更新为第一张 if(m_curIndex == m_pixmaps.count()) m_curIndex = 0; setNavType(m_navType); m_animation->setStartValue(0); m_animation->setEndValue(width()); m_animation->start(); //图片切换时,发送图片索引 emit currentIndexChange(m_curIndex); update(); }