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