Qt轮播图的实现代码,供大家参考,具体内容如下
qt轮播图简单的实现,功能会在后面完善
效果图:
这里我是用了QGraphicsScene+QGraphicsView+QGraphicsObject,其中对QGraphicsView和QGraphicsObject进行继承派生类功能进行了添加。时间有限,直接贴上关键代码部分供大家参考。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
//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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
//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); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//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); } |
下面那行按钮实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
//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); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
//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个位置,根据需要改动 #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//帧数,每秒 #define DURATION_MS 500//移动一次图元经过时间,毫秒,不得低于帧数 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 |
下面是滚动的关键代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
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)])); //设置新的显示优先级 itemList[i]->setScale(pixmapScaleList[getIndexByRules(i,dir)]); //设置新的类型 itemList[i]->setType(getIndexByRules(i,dir)); //i==7-->最后一个图元移动完成 finishList.append(i); if (finishList.size() == 8) { //循环旋转图元表和图片表 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())); //转换因子不是1.0时进行转换设置 if (transScaleList[i] != (qreal)1.0) { itemList[i]->setScale(itemList[i]->scale()*transScaleList[i]); } } m_scene->invalidate(); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
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))); //计算增长倍数 } //启动定时器 m_timer->start(); } void MainWindow::nextItem() { rollItem(1,1); } void MainWindow::previousItem() { rollItem(-1,1); } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/h391998495979/article/details/101868838