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


    一、简介

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

    二、详解

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

    (1)sliderpicture.h

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

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

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

    (1)parallaxhome.h

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

    运行效果图:

    三、总结

    (1)代码可以应用到相应的项目中,但相应功能还需要自定义开发。
    (2)此源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8674131)。
    (3)若有建议,请留言,在此先感谢!
     
    0
  • 相关阅读:
    BZOJ3562 : [SHOI2014]神奇化合物
    BZOJ3559 : [Ctsc2014]图的分割
    BZOJ3551 : [ONTAK2010]Peaks加强版
    BZOJ3542:DZY Loves March
    李洪强iOS开发之
    iOS学习之iOS沙盒(sandbox)机制和文件操作1
    iOS学习之iOS沙盒(sandbox)机制和文件操作
    stringByAppendingPathComponent和stringByAppendingString 的区别
    iOS开发:Toast for iPhone
    深度解析开发项目之 01
  • 原文地址:https://www.cnblogs.com/subo_peng/p/5361668.html
Copyright © 2020-2023  润新知