Qt浅谈之二十六图片滑动效果

一、简介

博客中发现有作者写的仿360的代码,觉得其中图片滑动的效果很有意思,特提取其中的代码。并加上类似mac的画面移动的动画效果。

二、详解

1、代码一:界面滑动(QWidget)

(1)sliderpicture.h

  1. #ifndef SLIDERPICTURE_H
  2. #define SLIDERPICTURE_H
  3. #include <QApplication>
  4. #include <QWidget>
  5. #include <QPushButton>
  6. #include <QMouseEvent>
  7. #include <QPainter>
  8. #include <QLabel>
  9. #include <QHBoxLayout>
  10. #include <QVector>
  11. #include <QDebug>
  12. /************SliderPicture**************/
  13. class PushButton;
  14. class PixLabel;
  15. class SliderPicture : public QWidget
  16. {
  17. Q_OBJECT
  18. public:
  19. explicit SliderPicture(QWidget *parent = 0);
  20. ~SliderPicture();
  21. protected:
  22. void mousePressEvent(QMouseEvent *event);
  23. void mouseReleaseEvent(QMouseEvent *event);
  24. void mouseMoveEvent(QMouseEvent *event);
  25. void keyPressEvent(QKeyEvent *event);
  26. private:
  27. void moveCurrentPage(bool);
  28. void setLabelMove(bool);
  29. private:
  30. PushButton *close_button;
  31. QLabel *background_label;
  32. QPoint m_mouseSrcPos;
  33. QPoint m_mouseDstPos;
  34. bool mouse_press;
  35. bool mouse_move;
  36. bool label_move;
  37. int current_index;
  38. QLabel *total_label;
  39. QVector<PixLabel*>label_array;
  40. int current_pos_x;
  41. private slots:
  42. void changeCurrentPage(PixLabel *label);
  43. };
  44. /************PushButton**************/
  45. class PushButton : public QPushButton
  46. {
  47. Q_OBJECT
  48. public:
  49. explicit PushButton(QWidget *parent = 0);
  50. ~PushButton();
  51. void setPicName(QString pic_name);
  52. protected:
  53. void enterEvent(QEvent *);
  54. void leaveEvent(QEvent *);
  55. void mousePressEvent(QMouseEvent *event);
  56. void mouseReleaseEvent(QMouseEvent *event);
  57. void paintEvent(QPaintEvent *);
  58. private:
  59. enum ButtonStatus{NORMAL, ENTER, PRESS, NOSTATUS};
  60. ButtonStatus status;
  61. QString pic_name;
  62. int btn_width;
  63. int btn_height;
  64. bool mouse_press;
  65. };
  66. /************CLabel**************/
  67. class PixLabel : public QWidget
  68. {
  69. Q_OBJECT
  70. public:
  71. explicit PixLabel(QWidget *parent = 0);
  72. ~PixLabel();
  73. void setPixmap(const QPixmap &);
  74. void setText(const QString &);
  75. void setMouseEnterFlag(bool);
  76. void setMousePressFlag(bool);
  77. protected:
  78. void enterEvent(QEvent *);
  79. void leaveEvent(QEvent *);
  80. void mousePressEvent(QMouseEvent *);
  81. void paintEvent(QPaintEvent *);
  82. signals:
  83. void signalLabelPress(PixLabel *);
  84. private:
  85. void initVariable();
  86. void initSetupUi();
  87. void createFrame();
  88. void createWidget();
  89. void createLayout();
  90. void paintWidget(int, QPainter *);
  91. bool getMouseEnterFlag();
  92. bool getMousePressFlag();
  93. bool m_mouseEnterFlag;
  94. bool m_mousePressFlag;
  95. QHBoxLayout *m_pHLayout;
  96. QLabel *m_pLabelIcon;
  97. QLabel *m_pLabelText;
  98. };
  99. #endif // SLIDERPICTURE_H

(2)sliderpicture.cpp

  1. #include "sliderpicture.h"
  2. SliderPicture::SliderPicture(QWidget *parent)
  3. : QWidget(parent)
  4. , mouse_press(false)
  5. , mouse_move(false)
  6. , label_move(true)
  7. , current_index(0)
  8. , current_pos_x(0)
  9. {
  10. setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
  11. resize(680, 370);
  12. background_label = new QLabel(this);
  13. background_label->setPixmap(QPixmap(":/bg_bottom"));
  14. background_label->setGeometry(QRect(0, 0, this->width(), this->height()));
  15. QPixmap pixmap(QSize(this->width()*4, this->height()));
  16. QPainter painter(&pixmap);
  17. for(int i = 0; i < 4; i++){
  18. painter.drawImage(QRect(this->width()*i, 0, this->width(), this->height()),
  19. QImage(QString(":/desktop_%1").arg(i)));
  20. }
  21. total_label = new QLabel(this);
  22. total_label->resize(pixmap.size());
  23. total_label->setPixmap(pixmap);
  24. total_label->move(0, 0);
  25. for(int index = 0; index < 4; index++) {
  26. PixLabel *label = new PixLabel(this);
  27. label->resize(QSize(155, 45));
  28. label->setPixmap(QPixmap(QString(":/btn_%1").arg(index)));
  29. if (index == 0) {
  30. label->setText(tr("function"));
  31. }
  32. else if (index == 1) {
  33. label->setText(tr("clearcookie"));
  34. }
  35. else if (index == 2) {
  36. label->setText(tr("triggerman"));
  37. }
  38. else {
  39. label->setText(tr("booster"));
  40. }
  41. label->move(8+index*170, 319);
  42. connect(label, SIGNAL(signalLabelPress(PixLabel*)), this, SLOT(changeCurrentPage(PixLabel*)));
  43. label_array.append(label);
  44. }
  45. label_array.first()->setMousePressFlag(true);
  46. label_array.first()->setFocus();
  47. close_button = new PushButton(this);
  48. close_button->setPicName(":/close");
  49. close_button->move(this->width()-close_button->width(), 0);
  50. close_button->setToolTip(tr("close"));
  51. connect(close_button, SIGNAL(clicked()), this, SLOT(close()));
  52. }
  53. SliderPicture::~SliderPicture()
  54. {
  55. }
  56. void SliderPicture::mousePressEvent(QMouseEvent *event)
  57. {
  58. if(event->button() == Qt::LeftButton) {
  59. m_mouseSrcPos = event->pos();
  60. if(m_mouseSrcPos.y() <= 40) {
  61. mouse_move = true;
  62. }
  63. else {
  64. current_pos_x = total_label->x();
  65. mouse_press = true;
  66. }
  67. }
  68. else if(event->button() == Qt::RightButton) {
  69. if(label_move) {
  70. if(current_index > 0) {
  71. current_index--;
  72. moveCurrentPage(false);  //move right
  73. }
  74. }
  75. }
  76. }
  77. void SliderPicture::mouseReleaseEvent(QMouseEvent *event)
  78. {
  79. int xpos = 0;
  80. if (mouse_press) {
  81. if (label_move) {
  82. m_mouseDstPos = event->pos();
  83. xpos = m_mouseDstPos.x() - m_mouseSrcPos.x();
  84. if (xpos > 0) {                     //the plan is:move right
  85. if(xpos >= 150) {               //mouse gap
  86. if(current_index > 0) {     //move right
  87. current_index--;
  88. moveCurrentPage(false);
  89. }
  90. else {
  91. moveCurrentPage(true);  //move left
  92. }
  93. }
  94. else {
  95. moveCurrentPage(true);     //move left
  96. }
  97. }
  98. else {             //the plan is:move right
  99. if(xpos <= -150)
  100. {
  101. if(current_index < 4-1) {
  102. current_index++;
  103. moveCurrentPage(true);  //move left
  104. }
  105. else {
  106. moveCurrentPage(false); //move right
  107. }
  108. }
  109. else {
  110. moveCurrentPage(false);     //move right
  111. }
  112. }
  113. }
  114. mouse_press = false;
  115. }
  116. else if(mouse_move){
  117. mouse_move = false;
  118. }
  119. }
  120. void SliderPicture::mouseMoveEvent(QMouseEvent *event)
  121. {
  122. int xPos = 0;
  123. if(mouse_press) {
  124. if(label_move) {
  125. m_mouseDstPos = event->pos();
  126. xPos = m_mouseDstPos.x() - m_mouseSrcPos.x();
  127. setLabelMove(false);
  128. total_label->move(current_pos_x + xPos, 0);
  129. setLabelMove(true);
  130. }
  131. }
  132. else if(mouse_move) {
  133. m_mouseDstPos = event->pos();
  134. this->move(this->pos() + m_mouseDstPos - m_mouseSrcPos);
  135. }
  136. }
  137. void SliderPicture::keyPressEvent(QKeyEvent *event)
  138. {
  139. if(label_move) {
  140. switch(event->key()) {
  141. case Qt::Key_Left:
  142. case Qt::Key_Up:
  143. if(current_index > 0) {
  144. current_index--;
  145. moveCurrentPage(false);    //move right
  146. }
  147. break;
  148. case Qt::Key_Right:
  149. case Qt::Key_Down:
  150. if(current_index < 4-1) {
  151. current_index++;
  152. moveCurrentPage(true);     //move left
  153. }
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. }
  160. void SliderPicture::moveCurrentPage(bool direction)
  161. {
  162. //change all label
  163. for(int i=0; i<4; i++) {
  164. if(i != current_index) {
  165. label_array.at(i)->setMousePressFlag(false);
  166. }
  167. else{
  168. label_array.at(i)->setMousePressFlag(true);
  169. }
  170. }
  171. //split point of picture
  172. //0-680 680-1360 1360-2040 2040-2720
  173. //true:left     false:right
  174. //index=0, move -680*0
  175. //index=1, move -680*1
  176. //index=2, move-680*2
  177. //index=3, move-680*3
  178. setLabelMove(false);
  179. int current_pos_x = total_label->x();    //label position
  180. int dest_pos_x = -680 * current_index;
  181. if(direction) {
  182. while(current_pos_x > dest_pos_x) {
  183. total_label->move(current_pos_x-20, 0);
  184. current_pos_x = total_label->x();
  185. qApp->processEvents(QEventLoop::AllEvents);
  186. }
  187. }
  188. else {
  189. while(current_pos_x < dest_pos_x) {
  190. total_label->move(current_pos_x+20, 0);
  191. current_pos_x = total_label->x();
  192. qApp->processEvents(QEventLoop::AllEvents);
  193. }
  194. }
  195. total_label->move(dest_pos_x, 0);
  196. setLabelMove(true);
  197. }
  198. void SliderPicture::setLabelMove(bool enable)
  199. {
  200. label_move = enable;
  201. }
  202. void SliderPicture::changeCurrentPage(PixLabel *label)
  203. {
  204. int index = 0;
  205. for(int iter = 0; iter < 4; iter++) {
  206. if(label != label_array.at(iter)) {
  207. label_array.at(iter)->setMousePressFlag(false);
  208. }
  209. else {
  210. index = iter;                //get the clicked label of index
  211. }
  212. }
  213. if(index < current_index) {          //move left
  214. while(index != current_index) {
  215. current_index--;
  216. moveCurrentPage(false);
  217. }
  218. }
  219. else if(index > current_index) {     //move right
  220. while(index != current_index) {
  221. current_index++;
  222. moveCurrentPage(true);
  223. }
  224. }
  225. }
  226. /************PushButton**************/
  227. PushButton::PushButton(QWidget *parent)
  228. : QPushButton(parent)
  229. {
  230. status = NORMAL;
  231. mouse_press = false;
  232. }
  233. PushButton::~PushButton()
  234. {
  235. }
  236. void PushButton::setPicName(QString pic_name)
  237. {
  238. this->pic_name = pic_name;
  239. setFixedSize(QPixmap(pic_name).size());
  240. }
  241. void PushButton::enterEvent(QEvent *)
  242. {
  243. status = ENTER;
  244. update();
  245. }
  246. void PushButton::mousePressEvent(QMouseEvent *event)
  247. {
  248. if(event->button() == Qt::LeftButton) {
  249. mouse_press = true;
  250. status = PRESS;
  251. update();
  252. }
  253. }
  254. void PushButton::mouseReleaseEvent(QMouseEvent *event)
  255. {
  256. if(mouse_press  && this->rect().contains(event->pos())) {
  257. mouse_press = false;
  258. status = ENTER;
  259. update();
  260. emit clicked();
  261. }
  262. }
  263. void PushButton::leaveEvent(QEvent *)
  264. {
  265. status = NORMAL;
  266. update();
  267. }
  268. void PushButton::paintEvent(QPaintEvent *)
  269. {
  270. QPainter painter(this);
  271. QPixmap pixmap;
  272. switch(status) {
  273. case NORMAL: {
  274. pixmap.load(pic_name);
  275. break;
  276. }
  277. case ENTER: {
  278. pixmap.load(pic_name + QString("_hover"));
  279. break;
  280. }
  281. case PRESS: {
  282. pixmap.load(pic_name + QString("_pressed"));
  283. break;
  284. }
  285. case NOSTATUS: {
  286. pixmap.load(pic_name);
  287. break;
  288. }
  289. default:
  290. pixmap.load(pic_name);
  291. }
  292. painter.drawPixmap(rect(), pixmap);
  293. }
  294. /************PixLabel**************/
  295. PixLabel::PixLabel(QWidget *parent)
  296. : QWidget(parent)
  297. {
  298. initVariable();
  299. initSetupUi();
  300. }
  301. PixLabel::~PixLabel()
  302. {
  303. delete m_pLabelIcon;
  304. delete m_pLabelText;
  305. delete m_pHLayout;
  306. }
  307. void PixLabel::setPixmap(const QPixmap &pixmap)
  308. {
  309. m_pLabelIcon->setPixmap(pixmap.scaled(QSize(30, 30), Qt::KeepAspectRatio, Qt::SmoothTransformation));
  310. }
  311. void PixLabel::setText(const QString &text)
  312. {
  313. m_pLabelText->setText(text);
  314. }
  315. void PixLabel::setMouseEnterFlag(bool flag)
  316. {
  317. m_mouseEnterFlag = flag;
  318. this->update();
  319. }
  320. void PixLabel::setMousePressFlag(bool flag)
  321. {
  322. m_mousePressFlag = flag;
  323. this->update();
  324. }
  325. void PixLabel::enterEvent(QEvent *)
  326. {
  327. if(!getMousePressFlag()) {
  328. setMouseEnterFlag(true);
  329. }
  330. this->setCursor(Qt::PointingHandCursor);
  331. }
  332. void PixLabel::leaveEvent(QEvent *)
  333. {
  334. setMouseEnterFlag(false);
  335. }
  336. void PixLabel::mousePressEvent(QMouseEvent *e)
  337. {
  338. if(e->button() == Qt::LeftButton) {
  339. setMousePressFlag(true);
  340. emit signalLabelPress(this);
  341. }
  342. }
  343. void PixLabel::paintEvent(QPaintEvent *e)
  344. {
  345. QPainter painter(this);
  346. if(getMouseEnterFlag()) {
  347. paintWidget(50, &painter);
  348. }
  349. else if(getMousePressFlag()) {
  350. paintWidget(80, &painter);
  351. }
  352. QWidget::paintEvent(e);
  353. }
  354. void PixLabel::initVariable()
  355. {
  356. setMouseEnterFlag(false);
  357. setMousePressFlag(false);
  358. }
  359. void PixLabel::initSetupUi()
  360. {
  361. createFrame();
  362. createWidget();
  363. createLayout();
  364. }
  365. void PixLabel::createFrame()
  366. {
  367. this->setStyleSheet("QWidget{background:transparent;border:0px;color:white;font-weight:bold;font-size:16px;}");
  368. }
  369. void PixLabel::createWidget()
  370. {
  371. m_pLabelIcon = new QLabel(this);
  372. m_pLabelText = new QLabel(this);
  373. }
  374. void PixLabel::createLayout()
  375. {
  376. m_pHLayout = new QHBoxLayout;
  377. m_pHLayout->setSpacing(10);
  378. m_pHLayout->setContentsMargins(QMargins(5, 0, 5, 0));
  379. m_pHLayout->addWidget(m_pLabelIcon);
  380. m_pHLayout->addWidget(m_pLabelText);
  381. m_pHLayout->addStretch();
  382. this->setLayout(m_pHLayout);
  383. }
  384. void PixLabel::paintWidget(int transparency, QPainter *device)
  385. {
  386. QPen pen(Qt::NoBrush, 1);
  387. device->setPen(pen);
  388. QLinearGradient linear(this->rect().topLeft(), this->rect().bottomLeft());
  389. linear.setColorAt(0, QColor(255, 255, 255, transparency));
  390. QBrush brush(linear);
  391. device->setBrush(brush);
  392. device->drawRoundedRect(this->rect(), 2, 2);
  393. }
  394. inline bool PixLabel::getMouseEnterFlag()
  395. {
  396. return m_mouseEnterFlag;
  397. }
  398. inline bool PixLabel::getMousePressFlag()
  399. {
  400. return m_mousePressFlag;
  401. }

(3)main.cpp

  1. #include "sliderpicture.h"
  2. #include <QApplication>
  3. #include <QTranslator>
  4. int main(int argc, char *argv[])
  5. {
  6. QApplication a(argc, argv);
  7. QTranslator translator;
  8. translator.load("sliderpicture.qm",":/");
  9. a.installTranslator(&translator);
  10. SliderPicture w;
  11. w.show();
  12. return a.exec();
  13. }

运行部分效果图(可以通过鼠标滑动或通过键盘方向键控制或者点击下方按钮):

Qt浅谈之二十六图片滑动效果Qt浅谈之二十六图片滑动效果

2、代码二:按钮滑动(QGraphicsItem)

(1)parallaxhome.h

  1. #ifndef PARALLAXHOME
  2. #define PARALLAXHOME
  3. #include <QtCore>
  4. #include <QtGui>
  5. #include <QtSvg>
  6. class NaviBar : public QObject, public QGraphicsRectItem
  7. {
  8. Q_OBJECT
  9. public:
  10. NaviBar(QGraphicsItem *parent = 0);
  11. void setPageOffset(qreal ofs);
  12. QRectF rect() const;
  13. signals:
  14. void pageSelected(int page);
  15. protected:
  16. void mousePressEvent(QGraphicsSceneMouseEvent *event);
  17. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
  18. private:
  19. QList<QGraphicsSvgItem *> m_icons;
  20. QGraphicsRectItem *m_cursor;
  21. };
  22. class ParallaxHome: public QGraphicsView
  23. {
  24. Q_OBJECT
  25. public:
  26. ParallaxHome(QWidget *parent = 0);
  27. private:
  28. QGraphicsScene m_scene;
  29. NaviBar *m_naviBar;
  30. QGraphicsPixmapItem *m_wallpaper;
  31. QTimeLine m_pageAnimator;
  32. qreal m_pageOffset;
  33. QList<QGraphicsPixmapItem*> m_items;
  34. QList<QPointF> m_positions;
  35. bool mouse_move;
  36. QPoint m_mouseSrcPos;
  37. QPoint m_mouseDstPos;
  38. signals:
  39. void pageChanged(int page);
  40. public slots:
  41. void slideRight();
  42. void slideLeft();
  43. void slideBy(int dx);
  44. void choosePage(int page);
  45. private slots:
  46. void shiftPage(int frame);
  47. protected:
  48. void resizeEvent(QResizeEvent *event);
  49. void keyPressEvent(QKeyEvent *event);
  50. void mousePressEvent(QMouseEvent *event);
  51. void mouseReleaseEvent(QMouseEvent *event);
  52. void mouseMoveEvent(QMouseEvent *event);
  53. void leaveEvent ( QEvent *event);
  54. void enterEvent(QEvent *event);
  55. private:
  56. void layoutScene();
  57. void setupScene();
  58. };
  59. #endif // PARALLAXHOME

(2)parallaxhome.cpp

  1. #include "parallaxhome.h"
  2. #define PAGE_COUNT 5
  3. #define ICON_SIZE 50
  4. #define ICON_PAD 4
  5. NaviBar::NaviBar(QGraphicsItem *parent)
  6. : QGraphicsRectItem(parent)
  7. {
  8. setAcceptHoverEvents(true);
  9. setRect(0, 0, 5 * ICON_SIZE, ICON_SIZE);
  10. setPen(Qt::NoPen);
  11. QStringList names;
  12. names << "map" << "web" << "home" << "weather" << "contacts";
  13. for (int i = 0; i < names.count(); ++i) {
  14. QString fname = names[i];
  15. fname.prepend(":/icons/");
  16. fname.append("-page.svg");
  17. QGraphicsSvgItem *icon = new QGraphicsSvgItem(fname);
  18. icon->setParentItem(this);
  19. icon->setCursor(Qt::PointingHandCursor);
  20. const int dim = ICON_SIZE - ICON_PAD * 2;
  21. qreal sw = dim / icon->boundingRect().width();
  22. qreal sh = dim / icon->boundingRect().height();
  23. icon->setTransform(QTransform().scale(sw, sh));
  24. icon->setZValue(2);
  25. m_icons << icon;
  26. }
  27. m_cursor = new QGraphicsRectItem;
  28. m_cursor->setParentItem(this);
  29. m_cursor->setRect(0, 0, ICON_SIZE, ICON_SIZE);
  30. m_cursor->setZValue(1);
  31. m_cursor->setPen(Qt::NoPen);
  32. m_cursor->setBrush(QColor(Qt::white));
  33. m_cursor->setOpacity(0.6);
  34. }
  35. void NaviBar::setPageOffset(qreal ofs)
  36. {
  37. m_cursor->setPos(ofs * ICON_SIZE, 0);
  38. for (int i = 0; i < m_icons.count(); ++i) {
  39. int y = (i == static_cast<int>(ofs + 0.5)) ? ICON_PAD : ICON_PAD * 2;
  40. m_icons[i]->setPos(i * ICON_SIZE + ICON_PAD, y);
  41. m_icons[i]->setOpacity(1);
  42. }
  43. }
  44. QRectF NaviBar::rect() const
  45. {
  46. return QRectF(0, 0, 250, 50);
  47. }
  48. void NaviBar::mousePressEvent(QGraphicsSceneMouseEvent *event)
  49. {
  50. if (this->boundingRect().contains(event->pos())) {
  51. emit pageSelected(static_cast<int>(event->pos().x() / ICON_SIZE));
  52. }
  53. }
  54. void NaviBar::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  55. {
  56. painter->setBrush(Qt::white);
  57. painter->setOpacity(0.2);
  58. painter->drawRect(option->rect);
  59. //painter->drawRect(option->rect.adjusted(-20, ICON_PAD, 20, 0));
  60. }
  61. ParallaxHome::ParallaxHome(QWidget *parent)
  62. : QGraphicsView(parent)
  63. , m_pageOffset(-2)
  64. , mouse_move(false)
  65. {
  66. resize(360, 504);
  67. setWindowFlags(Qt::FramelessWindowHint);
  68. setupScene();
  69. setScene(&m_scene);
  70. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  71. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  72. setFrameShape(QFrame::NoFrame);
  73. setWindowTitle("Parallax Home");
  74. connect(&m_pageAnimator, SIGNAL(frameChanged(int)), SLOT(shiftPage(int)));
  75. m_pageAnimator.setDuration(500);
  76. m_pageAnimator.setFrameRange(0, 100);
  77. m_pageAnimator.setCurveShape(QTimeLine::EaseInCurve);
  78. pageChanged(static_cast<int>(m_pageOffset));
  79. move((QApplication::desktop()->width() - width())/2,  (QApplication::desktop()->height() - height())/2);
  80. }
  81. void ParallaxHome::slideRight()
  82. {
  83. if (m_pageAnimator.state() != QTimeLine::NotRunning)
  84. return;
  85. int edge = -(m_pageOffset - 1);
  86. if (edge < PAGE_COUNT)
  87. slideBy(-1);
  88. }
  89. void ParallaxHome::slideLeft()
  90. {
  91. if (m_pageAnimator.state() != QTimeLine::NotRunning)
  92. return;
  93. if (m_pageOffset < 0)
  94. slideBy(1);
  95. }
  96. void ParallaxHome::slideBy(int dx)
  97. {
  98. int start = m_pageOffset * 1000;
  99. int end = (m_pageOffset + dx) * 1000;
  100. m_pageAnimator.setFrameRange(start, end);
  101. m_pageAnimator.start();
  102. }
  103. void ParallaxHome::choosePage(int page)
  104. {
  105. if (m_pageAnimator.state() != QTimeLine::NotRunning)
  106. return;
  107. if (static_cast<int>(-m_pageOffset) == page)
  108. return;
  109. slideBy(-page - m_pageOffset);
  110. }
  111. void ParallaxHome::shiftPage(int frame)
  112. {
  113. int ww = width();
  114. int hh = height() - m_naviBar->rect().height();
  115. int oldPage = static_cast<int>(-m_pageOffset);
  116. m_pageOffset = static_cast<qreal>(frame) / qreal(1000);
  117. int newPage = static_cast<int>(-m_pageOffset);
  118. m_naviBar->setPageOffset(-m_pageOffset);
  119. if (oldPage != newPage)
  120. emit pageChanged(newPage);
  121. int ofs = m_pageOffset * ww;
  122. for (int i = 0; i < m_items.count(); ++i) {
  123. QPointF pos = m_positions[i];
  124. QPointF xy(pos.x() * ww, pos.y() * hh);
  125. m_items[i]->setPos(xy + QPointF(ofs, 0));
  126. }
  127. int center = m_wallpaper->pixmap().width() / 2;
  128. const int parallax = 3;
  129. int base = center - (ww / 2) - (PAGE_COUNT >> 1) * (ww / parallax);
  130. int wofs = base - m_pageOffset * ww / parallax;
  131. m_wallpaper->setPos(-wofs, 0);
  132. }
  133. void ParallaxHome::resizeEvent(QResizeEvent *event)
  134. {
  135. Q_UNUSED(event);
  136. layoutScene();
  137. }
  138. void ParallaxHome::keyPressEvent(QKeyEvent *event)
  139. {
  140. if (event->key() == Qt::Key_Right)
  141. slideRight();
  142. else if (event->key() == Qt::Key_Left)
  143. slideLeft();
  144. event->accept();
  145. }
  146. void ParallaxHome::mousePressEvent(QMouseEvent *event)
  147. {
  148. if(event->button() == Qt::LeftButton) {
  149. m_mouseSrcPos = event->pos();
  150. if(m_mouseSrcPos.y() <= 40) {
  151. mouse_move = true;
  152. }
  153. }
  154. QGraphicsView::mousePressEvent(event);
  155. }
  156. void ParallaxHome::mouseReleaseEvent(QMouseEvent *event)
  157. {
  158. if(mouse_move){
  159. mouse_move = false;
  160. }
  161. QGraphicsView::mouseReleaseEvent(event);
  162. }
  163. void ParallaxHome::mouseMoveEvent(QMouseEvent *event)
  164. {
  165. if(mouse_move) {
  166. m_mouseDstPos = event->pos();
  167. this->move(this->pos() + m_mouseDstPos - m_mouseSrcPos);
  168. }
  169. QGraphicsView::mouseMoveEvent(event);
  170. }
  171. void ParallaxHome::leaveEvent(QEvent *event)
  172. {
  173. }
  174. void ParallaxHome::enterEvent(QEvent *event)
  175. {
  176. }
  177. void ParallaxHome::layoutScene()
  178. {
  179. int ww = width();
  180. int hh = height();
  181. m_scene.setSceneRect(0, 0, PAGE_COUNT * ww - 1, hh - 1);
  182. centerOn(ww / 2, hh / 2);
  183. int nw = m_naviBar->rect().width();
  184. int nh = m_naviBar->rect().height();
  185. m_naviBar->setPos((ww - nw) / 2, hh - nh);
  186. shiftPage(m_pageOffset * 1000);
  187. }
  188. void ParallaxHome::setupScene()
  189. {
  190. qsrand(QTime::currentTime().second());
  191. QStringList names;
  192. names << "brownies" << "cookies" << "mussels" << "pizza" << "sushi";
  193. names << "chocolate" << "fish" << "pasta" << "puding" << "trouts";
  194. for (int i = 0; i < PAGE_COUNT * 2; ++i) {
  195. QString fname = names[i];
  196. fname.prepend(":/images/");
  197. fname.append(".jpg");
  198. QPixmap pixmap(fname);
  199. pixmap = pixmap.scaledToWidth(200);
  200. QGraphicsPixmapItem *item = m_scene.addPixmap(pixmap);
  201. m_items << item;
  202. qreal x = (i >> 1) + (qrand() % 30) / 100.0;
  203. qreal y = (i & 1) / 2.0  + (qrand() % 20) / 100.0;
  204. m_positions << QPointF(x, y);
  205. item->setZValue(1);
  206. }
  207. m_naviBar = new NaviBar;
  208. m_scene.addItem(m_naviBar);
  209. m_naviBar->setZValue(2);
  210. connect(m_naviBar, SIGNAL(pageSelected(int)), SLOT(choosePage(int)));
  211. m_wallpaper = m_scene.addPixmap(QPixmap(":/icons/surfacing.png"));
  212. m_wallpaper->setZValue(0);
  213. //m_scene.setItemIndexMethod(QGraphicsScene::NoIndex);
  214. QPushButton *close_button = new QPushButton(this);
  215. close_button->resize(27, 22);
  216. close_button->setFocusPolicy(Qt::NoFocus);
  217. close_button->setStyleSheet("QPushButton{border-style:flat;background-image:url(:/icons/close.png);}QPushButton:hover{background-image:url(:/icons/close_hover.png);}QPushButton:hover:pressed{background-image:url(:/icons/close_pressed.png);}");
  218. close_button->setCursor(Qt::PointingHandCursor);
  219. close_button->raise();
  220. close_button->move(this->width()-close_button->width(), 0);
  221. close_button->setToolTip(tr("close"));
  222. connect(close_button, SIGNAL(clicked()), this, SLOT(close()));
  223. }

(3)main.cpp

  1. #include "parallaxhome.h"
  2. int main(int argc, char *argv[])
  3. {
  4. QApplication app(argc, argv);
  5. ParallaxHome w;
  6. w.show();
  7. return app.exec();
  8. }

运行效果图:

Qt浅谈之二十六图片滑动效果Qt浅谈之二十六图片滑动效果

三、总结

(1)代码可以应用到相应的项目中,但相应功能还需要自定义开发。
(2)此源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8674131)。
(3)若有建议,请留言,在此先感谢!

 
0
上一篇:Asp.Net Core Web应用程序—探索


下一篇:JS 循环定时的一些思考