您好,登錄后才能下訂單哦!
這篇文章主要講解了Qt轉(zhuǎn)動輪播圖的實現(xiàn)方法,內(nèi)容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
Qt輪播圖的實現(xiàn)代碼,供大家參考,具體內(nèi)容如下
qt輪播圖簡單的實現(xiàn),功能會在后面完善
效果圖:
這里我是用了QGraphicsScene+QGraphicsView+QGraphicsObject,其中對QGraphicsView和QGraphicsObject進行繼承派生類功能進行了添加。時間有限,直接貼上關(guān)鍵代碼部分供大家參考。
//pictrueitem.h #ifndef PICTRUEITEM_H #define PICTRUEITEM_H #include <QGraphicsPixmapItem> #include <QGraphicsItem> #include <QGraphicsObject> #include <QPixmap> class PictrueItem : public QGraphicsObject { Q_OBJECT public: explicit PictrueItem(QGraphicsItem *parent = Q_NULLPTR); explicit PictrueItem(const QPixmap &pixmap, QGraphicsItem *parent = Q_NULLPTR); virtual ~PictrueItem(); void setPixmap(const QPixmap &pixmap); QPixmap pixmap() const; virtual QRectF boundingRect() const; void setTransformationMode(Qt::TransformationMode mode); QPointF offset() const; void setOffset(const QPointF &offset); virtual int type()const; void setType(int type); int itemId()const; void setItemId(int id); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); Q_SIGNALS: void clicked(); void clickedId(int); private: QPointF pressedScenePoint; QPointF m_offset; QPointF m_pos; Qt::TransformationMode mode; QPixmap m_pixmap; bool isPressed; int m_type; int m_id; qreal m_pointPercent; }; #endif // PICTRUEITEM_H
//pictrueitem.cpp #include "pictrueitem.h" #include <QGraphicsSceneMouseEvent> #include <QPainter> #include <QDebug> PictrueItem::PictrueItem(QGraphicsItem *parent) :QGraphicsObject(parent), isPressed(false), mode(Qt::SmoothTransformation), m_type(0), m_id(0), m_pointPercent((qreal)0.0) { } PictrueItem::PictrueItem(const QPixmap &pixmap, QGraphicsItem *parent) :QGraphicsObject(parent), isPressed(false), mode(Qt::SmoothTransformation), m_type(0) { m_pixmap = pixmap; } PictrueItem::~PictrueItem() { } void PictrueItem::setPixmap(const QPixmap &pixmap) { prepareGeometryChange(); m_pixmap = pixmap; update(); } QPixmap PictrueItem::pixmap() const { return m_pixmap; } QRectF PictrueItem::boundingRect() const { if(m_pixmap.isNull()) return QRectF(); return QRectF(m_offset, m_pixmap.size() / m_pixmap.devicePixelRatio()); } void PictrueItem::setTransformationMode(Qt::TransformationMode mode) { if (mode != this->mode) { this->mode = mode; update(); } } QPointF PictrueItem::offset() const { return m_offset; } void PictrueItem::setOffset(const QPointF &offset) { m_offset = offset; if (m_offset == offset) return; prepareGeometryChange(); m_offset = offset; update(); } int PictrueItem::type() const { return m_type; } void PictrueItem::setType(int type) { m_type = type; } int PictrueItem::itemId() const { return m_id; } void PictrueItem::setItemId(int id) { m_id = id; } void PictrueItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { //只響應鼠標左鍵 if(event->button() == Qt::LeftButton) { pressedScenePoint = event->pos(); isPressed = true; } } void PictrueItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if(event->button() == Qt::LeftButton){ if(isPressed && boundingRect().contains(event->pos()) && boundingRect().contains(pressedScenePoint)) { isPressed = false; emit clicked(); emit clickedId(type()); } } } void PictrueItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget); Q_UNUSED(option); painter->setRenderHint(QPainter::SmoothPixmapTransform, (this->mode == Qt::SmoothTransformation)); painter->drawPixmap(m_offset, m_pixmap); }
//pictrueview.h #ifndef PICTRUEVIEW_H #define PICTRUEVIEW_H #include <QGraphicsView> class PictrueView : public QGraphicsView { Q_OBJECT public: PictrueView(QWidget *parent = Q_NULLPTR); virtual ~PictrueView(); protected: void resizeEvent(QResizeEvent *event); public: Q_SIGNALS: void sizeChanged(const QSize &); }; #endif // PICTRUEVIEW_H
//pictrueview.cpp #include "pictrueview.h" #include <QResizeEvent> PictrueView::PictrueView(QWidget *parent) :QGraphicsView(parent) { } PictrueView::~PictrueView() { //none } void PictrueView::resizeEvent(QResizeEvent *event) { emit sizeChanged(event->size()); return QGraphicsView::resizeEvent(event); }
下面那行按鈕實現(xiàn)
//pictruebutton.h #ifndef PICTRUERADIOBUTTON_H #define PICTRUERADIOBUTTON_H #include <QAbstractButton> class PictrueButton : public QAbstractButton { Q_OBJECT public: explicit PictrueButton(QWidget *parent = Q_NULLPTR); ~PictrueButton(); int id()const; void setId(int id); Q_SIGNALS: void entered(); void entered(int); protected: virtual void paintEvent(QPaintEvent *); virtual void enterEvent(QEvent *event); virtual void leaveEvent(QEvent *event); private: bool m_isSelected; int m_id; }; #endif // PICTRUERADIOBUTTON_H
//pictruebutton.cpp #include "pictruebutton.h" #include <QPen> #include <QPainter> #include <QDebug> #include <QPainterPath> PictrueButton::PictrueButton(QWidget *parent) :QAbstractButton(parent), m_isSelected(false), m_id(0) { setCheckable(true); setFixedSize(50,10); } PictrueButton::~PictrueButton() { } int PictrueButton::id() const { return m_id; } void PictrueButton::setId(int id) { m_id = id; } void PictrueButton::paintEvent(QPaintEvent *) { QPainter painter(this); QRectF drawRect = this->rect(); QPainterPath drawPath; qDebug()<<drawRect; QPen drawPen; drawPen.setWidth(3); //選中為藍,未選中為灰 drawPen.setColor(Qt::gray); painter.setPen(drawPen); //抗鋸齒 painter.setRenderHint(QPainter::Antialiasing); drawPath.addRoundedRect(drawRect,10,10); painter.setClipPath(drawPath); if(isChecked()) painter.fillRect(drawRect,QColor(0,0,255,128)); else painter.fillRect(drawRect,QColor(128,128,128,128)); } void PictrueButton::enterEvent(QEvent *event) { if(!isChecked()) setChecked(true); emit entered(m_id); return QAbstractButton::enterEvent(event); } void PictrueButton::leaveEvent(QEvent *event) { return QAbstractButton::leaveEvent(event); }
//qmainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #define RAW_VIEW_SIZE QSize(476,414) #define SCALE_VIEW_PIXMAP (qreal)2/1 //View與圖片比例 #define SCALE_BIG_SMALL (qreal)2/1 //圖片大小比例 //P1-P8,8個位置,根據(jù)需要改動 #define P1 (qreal)0.00 #define P2 (qreal)0.25 #define P3 (qreal)0.50 #define P4 (qreal)0.75 #define P5 (qreal)1.00 #define P6 P4 #define P7 P3 #define P8 P2 #define MID_TYPE 2 #define FPS 60//幀數(shù),每秒 #define DURATION_MS 500//移動一次圖元經(jīng)過時間,毫秒,不得低于幀數(shù) namespace Ui { class MainWindow; } class QGraphicsScene; class QButtonGroup; class MainWindow : public QMainWindow { Q_OBJECT public: enum Rules:int{ RuleA = 1, RuleB = -1, RuleC = 2, RuleD = -2 }; explicit MainWindow(QWidget *parent = 0); ~MainWindow(); int getIndexByRules(int oldIndex,int rule); template<typename T> void rollList(QList<T> &oldList, int dir, int count); void rollItem(int rollDir,unsigned rollCount); public Q_SLOTS: void timerOutFunc(); void nextItem(); void previousItem(); void clickedItemRoll(int type); protected: private: Ui::MainWindow *ui; QTimer *m_timer; QGraphicsScene *m_scene; QLineF midLine; QList<qreal> pointList; QList<QPixmap> pixmapList; QList<qreal> zValueList; QList<qreal> pixmapScaleList; int m_index; Rules currentRule; unsigned m_rollCount; QButtonGroup *btnGroup; bool btnMoveEnable; }; #endif // MAINWINDOW_H
下面是滾動的關(guān)鍵代碼
void MainWindow::timerOutFunc() { for(int i = 0; i<8; i++) { if(qAbs(midLine.pointAt(pointList[getIndexByRules(i,dir)]).x()-itemList[i]->pos().x())<qAbs(unitList[i])) { if(finishList.contains(i)) continue; itemList[i]->setPos(midLine.pointAt(pointList[getIndexByRules(i,dir)])); //設(shè)置新的顯示優(yōu)先級 itemList[i]->setScale(pixmapScaleList[getIndexByRules(i,dir)]); //設(shè)置新的類型 itemList[i]->setType(getIndexByRules(i,dir)); //i==7-->最后一個圖元移動完成 finishList.append(i); if(finishList.size() == 8) { //循環(huán)旋轉(zhuǎn)圖元表和圖片表 rollList(itemList,dir,1); rollList(pixmapList,dir,1); for(int i = 0; i<8; i++) itemList[i]->setZValue(zValueList[i]); m_timer->stop(); finishList.clear(); if(btnGroup->checkedId()!=itemList[MID_TYPE]->itemId()) btnGroup->button(getIndexByRules(btnGroup->checkedId(),dir))->setChecked(true); if(--m_rollCount) { if(dir == 1) nextItem(); else previousItem(); } break; } } else { //按計算好的移動單位移動一次 itemList[i]->setPos(QPointF(itemList[i]->pos().x()+unitList[i],itemList[i]->pos().y())); //轉(zhuǎn)換因子不是1.0時進行轉(zhuǎn)換設(shè)置 if(transScaleList[i] != (qreal)1.0) { itemList[i]->setScale(itemList[i]->scale()*transScaleList[i]); } } m_scene->invalidate(); } }
void MainWindow::rollItem(int rollDir, unsigned rollCount) { if(m_timer->isActive()) return; //清除之前的空間差列表和移動單位列表 m_rollCount = rollCount; spaceList.clear(); unitList.clear(); transScaleList.clear(); dir = rollDir; qDebug()<<"rollCount"<<rollCount; for(int i = 0; i<8; i++) { spaceList.append(midLine.pointAt(pointList[getIndexByRules(i,dir)]).x()-itemList[i]->pos().x());//計算移動總距離 unitList.append(spaceList[i]/(FPS*DURATION_MS/1000));//計算移動單個距離 transScaleList.append(pow(pixmapScaleList[getIndexByRules(i,dir)]/pixmapScaleList[i],\ (qreal)1/(FPS*DURATION_MS/1000)));//計算增長倍數(shù) } //啟動定時器 m_timer->start(); } void MainWindow::nextItem() { rollItem(1,1); } void MainWindow::previousItem() { rollItem(-1,1); }
看完上述內(nèi)容,是不是對Qt轉(zhuǎn)動輪播圖的實現(xiàn)方法有進一步的了解,如果還想學習更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。