图片轮播c语言,Qt实现转动轮播图

Qt轮播图的实现代码,供大家参考,具体内容如下

qt轮播图简单的实现,功能会在后面完善

效果图:

84a03a4c48e1af9e25fc98169eca9430.gif

这里我是用了QGraphicsScene+QGraphicsView+QGraphicsObject,其中对QGraphicsView和QGraphicsObject进行继承派生类功能进行了添加。时间有限,直接贴上关键代码部分供大家参考。

//pictrueitem.h

#ifndef PICTRUEITEM_H

#define PICTRUEITEM_H

#include

#include

#include

#include

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

#include

#include

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

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

PictrueView::PictrueView(QWidget *parent)

:QGraphicsView(parent)

{

}

PictrueView::~PictrueView()

{

//none

}

void PictrueView::resizeEvent(QResizeEvent *event)

{

emit sizeChanged(event->size());

return QGraphicsView::resizeEvent(event);

}

下面那行按钮实现

//pictruebutton.h

#ifndef PICTRUERADIOBUTTON_H

#define PICTRUERADIOBUTTON_H

#include

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

#include

#include

#include

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()<

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

#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

void rollList(QList &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 pointList;

QList pixmapList;

QList zValueList;

QList pixmapScaleList;

int m_index;

Rules currentRule;

unsigned m_rollCount;

QButtonGroup *btnGroup;

bool btnMoveEnable;

};

#endif // MAINWINDOW_H

下面是滚动的关键代码

void MainWindow::timerOutFunc()

{

for(int i = 0; i<8; i++)

{

if(qAbs(midLine.pointAt(pointList[getIndexByRules(i,dir)]).x()-itemList[i]->pos().x())

{

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();

}

}

void MainWindow::rollItem(int rollDir, unsigned rollCount)

{

if(m_timer->isActive())

return;

//清除之前的空间差列表和移动单位列表

m_rollCount = rollCount;

spaceList.clear();

unitList.clear();

transScaleList.clear();

dir = rollDir;

qDebug()<

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);

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值