zoukankan      html  css  js  c++  java
  • Qt使用QGraphicsView实现滑动窗体效果

    源码已上传至CSDN,http://download.csdn.net/source/2808505

    QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容。QGraphicsScene提供了QGraphicsItem的容器功能。通常与QGraphicsView一起使用来描述可视化图形项目。

    QGraphicsScene提供了一个视图的场景,通过在这样一个场景之上加入不同的QGraphicsItem来构建视图。而QGraphicsView则提供了一个widget来显示QGraphicsScene的内容。所以要想成功构建一个视图,这三个元素缺一不可。

    以下是一个QGraphicsView的例子,实现滑动的窗体效果,工具栏和图片均为场景中的Item。

    [cpp] view plaincopy
     
    1. #include <QtCore>  
    2. #include <QtGui>  
    3. #include <QtSvg>  
    4. /*程序中用到了svg格式的图片,所以需包含QtSvg*/  
    5. #define PAGE_COUNT 5  
    6. /*定义滑动窗体的窗体数*/  

    定义工具栏,NviBar继承自QGraphicsRectItem,用法与QGraphicsItem类似。

    [cpp] view plaincopy
     
    1. class NaviBar : public QObject, public QGraphicsRectItem  
    2. {  
    3.     Q_OBJECT  
    4. public:  
    5.     NaviBar();  
    6.     void setPageOffset(qreal ofs);  
    7. signals:  
    8.     void pageSelected(int page);  
    9. protected:  
    10.     void mousePressEvent(QGraphicsSceneMouseEvent *event);  
    11.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);  
    12. private:  
    13.     QList<QGraphicsSvgItem*> m_icons;  
    14.     QGraphicsRectItem *m_cursor;  
    15. };  

    函数实现

    [cpp] view plaincopy
     
    1. #define ICON_SIZE 50  
    2. #define ICON_PAD 4  
    3. NaviBar::NaviBar()  
    4.         : QGraphicsRectItem()  
    5. {  
    6.     setRect(0, 0, 5 * ICON_SIZE, ICON_SIZE);  
    7.     setPen(Qt::NoPen);  
    8.     QStringList names;  
    9.     names << "map" << "web" << "home" << "weather" << "contacts";  
    10.     for (int i = 0; i < names.count(); ++i) {  
    11.         QString fname = names[i];  
    12.         fname.prepend(":/icons/");  
    13.         fname.append("-page.svg");  
    14.         QGraphicsSvgItem *icon = new QGraphicsSvgItem(fname);  
    15.         icon->setParentItem(this);  
    16.         const int dim = ICON_SIZE - ICON_PAD * 2;  
    17.         qreal sw = dim / icon->boundingRect().width();  
    18.         qreal sh = dim / icon->boundingRect().height();  
    19.         icon->setTransform(QTransform().scale(sw, sh));  
    20.         icon->setZValue(2);  
    21.         m_icons << icon;  
    22.     }  
    23.     m_cursor = new QGraphicsRectItem;  
    24.     m_cursor->setParentItem(this);  
    25.     m_cursor->setRect(0, 0, ICON_SIZE, ICON_SIZE);  
    26.     m_cursor->setZValue(1);  
    27.     m_cursor->setPen(Qt::NoPen);  
    28.     m_cursor->setBrush(QColor(Qt::white));  
    29.     m_cursor->setOpacity(0.6);  
    30. }  
    31. void NaviBar::setPageOffset(qreal ofs)  
    32. {  
    33.     m_cursor->setPos(ofs * ICON_SIZE, 0);  
    34.     for (int i = 0; i < m_icons.count(); ++i) {  
    35.         int y = (i == static_cast<int>(ofs + 0.5)) ? ICON_PAD : ICON_PAD * 2;  
    36.         m_icons[i]->setPos(i * ICON_SIZE + ICON_PAD, y);  
    37.         m_icons[i]->setOpacity(1);  
    38.     }  
    39. }  
    40. void NaviBar::mousePressEvent(QGraphicsSceneMouseEvent *event)  
    41. {  
    42.     emit pageSelected(static_cast<int>(event->pos().x() / ICON_SIZE));  
    43. }  
    44. void NaviBar::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)  
    45. {  
    46.     painter->setBrush(Qt::white);  
    47.     painter->setOpacity(0.2);  
    48.     painter->drawRect(option->rect.adjusted(-20, ICON_PAD, 20, 0));  
    49. }  

    定义视图

    [cpp] view plaincopy
     
    1. class ParallaxHome: public QGraphicsView  
    2. {  
    3.     Q_OBJECT  
    4. public:  
    5.     QGraphicsScene m_scene;  
    6.     NaviBar *m_naviBar;  
    7.     QGraphicsPixmapItem *m_wallpaper;  
    8.     QTimeLine m_pageAnimator;  
    9.     qreal m_pageOffset;  
    10.     QList<QGraphicsPixmapItem*> m_items;  
    11.     QList<QPointF> m_positions;  
    12. public:  
    13.     ParallaxHome(QWidget *parent = 0)  
    14.             : QGraphicsView(parent)  
    15.             , m_pageOffset(-2) {  
    16.         setupScene();  
    17.         setScene(&m_scene);  
    18.         setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);  
    19.         setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);  
    20.         setFrameShape(QFrame::NoFrame);  
    21.         setWindowTitle("Parallax Home");  
    22.         connect(&m_pageAnimator, SIGNAL(frameChanged(int)), SLOT(shiftPage(int)));  
    23.         m_pageAnimator.setDuration(500);  
    24.         m_pageAnimator.setFrameRange(0, 100);  
    25.         m_pageAnimator.setCurveShape(QTimeLine::EaseInCurve);  
    26.         pageChanged(static_cast<int>(m_pageOffset));  
    27.     }  
    28. signals:  
    29.     void pageChanged(int page);  
    30. public slots:  
    31.     void slideRight() {  
    32.         if (m_pageAnimator.state() != QTimeLine::NotRunning)  
    33.             return;  
    34.         int edge = -(m_pageOffset - 1);  
    35.         if (edge < PAGE_COUNT)  
    36.             slideBy(-1);  
    37.     }  
    38.     void slideLeft() {  
    39.         if (m_pageAnimator.state() != QTimeLine::NotRunning)  
    40.             return;  
    41.         if (m_pageOffset < 0)  
    42.             slideBy(1);  
    43.     }  
    44.     void slideBy(int dx) {  
    45.         int start = m_pageOffset * 1000;  
    46.         int end = (m_pageOffset + dx) * 1000;  
    47.         m_pageAnimator.setFrameRange(start, end);  
    48.         m_pageAnimator.start();  
    49.     }  
    50.     void choosePage(int page) {  
    51.         if (m_pageAnimator.state() != QTimeLine::NotRunning)  
    52.             return;  
    53.         if (static_cast<int>(-m_pageOffset) == page)  
    54.             return;  
    55.         slideBy(-page - m_pageOffset);  
    56.     }  
    57. private slots:  
    58.     void shiftPage(int frame) {  
    59.         int ww = width();  
    60.         int hh = height() - m_naviBar->rect().height();  
    61.         int oldPage = static_cast<int>(-m_pageOffset);  
    62.         m_pageOffset = static_cast<qreal>(frame) / qreal(1000);  
    63.         int newPage = static_cast<int>(-m_pageOffset);  
    64.         m_naviBar->setPageOffset(-m_pageOffset);  
    65.         if (oldPage != newPage)  
    66.             emit pageChanged(newPage);  
    67.         int ofs = m_pageOffset * ww;  
    68.         for (int i = 0; i < m_items.count(); ++i) {  
    69.             QPointF pos = m_positions[i];  
    70.             QPointF xy(pos.x() * ww, pos.y() * hh);  
    71.             m_items[i]->setPos(xy + QPointF(ofs, 0));  
    72.         }  
    73.         int center = m_wallpaper->pixmap().width() / 2;  
    74.         const int parallax = 3;  
    75.         int base = center - (ww / 2) - (PAGE_COUNT >> 1) * (ww / parallax);  
    76.         int wofs = base - m_pageOffset * ww / parallax;  
    77.         m_wallpaper->setPos(-wofs, 0);  
    78.     }  
    79. protected:  
    80.     void resizeEvent(QResizeEvent *event) {  
    81.         Q_UNUSED(event);  
    82.         layoutScene();  
    83.     }  
    84.     void keyPressEvent(QKeyEvent *event) {  
    85.         if (event->key() == Qt::Key_Right)  
    86.             slideRight();  
    87.         if (event->key() == Qt::Key_Left)  
    88.             slideLeft();  
    89.         event->accept();  
    90.     }  
    91. private:  
    92.     void layoutScene() {  
    93.         int ww = width();  
    94.         int hh = height();  
    95.         m_scene.setSceneRect(0, 0, PAGE_COUNT * ww - 1, hh - 1);  
    96.         centerOn(ww / 2, hh / 2);  
    97.         int nw = m_naviBar->rect().width();  
    98.         int nh = m_naviBar->rect().height();  
    99.         m_naviBar->setPos((ww - nw) / 2, hh - nh);  
    100.         shiftPage(m_pageOffset * 1000);  
    101.     }  
    102.     void setupScene() {  
    103.         qsrand(QTime::currentTime().second());  
    104.         QStringList names;  
    105.         names << "brownies" << "cookies" << "mussels" << "pizza" << "sushi";  
    106.         names << "chocolate" << "fish" << "pasta" << "puding" << "trouts";  
    107.         for (int i = 0; i < PAGE_COUNT * 2; ++i) {  
    108.             QString fname = names[i];  
    109.             fname.prepend(":/images/");  
    110.             fname.append(".jpg");  
    111.             QPixmap pixmap(fname);  
    112.             pixmap = pixmap.scaledToWidth(200);  
    113.             QGraphicsPixmapItem *item = m_scene.addPixmap(pixmap);  
    114.             m_items << item;  
    115.             qreal x = (i >> 1) + (qrand() % 30) / 100.0;  
    116.             qreal y = (i & 1) / 2.0  + (qrand() % 20) / 100.0;  
    117.             m_positions << QPointF(x, y);  
    118.             item->setZValue(1);  
    119.         }  
    120.         m_naviBar = new NaviBar;  
    121.         m_scene.addItem(m_naviBar);  
    122.         m_naviBar->setZValue(2);  
    123.         connect(m_naviBar, SIGNAL(pageSelected(int)), SLOT(choosePage(int)));  
    124.         m_wallpaper = m_scene.addPixmap(QPixmap(":/icons/surfacing.png"));  
    125.         m_wallpaper->setZValue(0);  
    126.         m_scene.setItemIndexMethod(QGraphicsScene::NoIndex);  
    127.     }  
    128. };  

    main函数

    [cpp] view plaincopy
     
    1. #include "parallaxhome.moc"  
    2. int main(int argc, char *argv[])  
    3. {  
    4.     QApplication app(argc, argv);  
    5.     ParallaxHome w;  
    6.     w.resize(360, 640);  
    7.     w.show();  
    8.     return app.exec();  
    9. }  

    http://blog.csdn.net/huihui1988/article/details/5725955

  • 相关阅读:
    Django错误笔记1
    Django学习笔记1 启动及配置一个Django项目
    ubuntu 安装mysqldb
    二叉树 总结
    序列二叉树和反序列 (不是自己做的)
    二叉树的路径
    二叉搜索树的后续遍历
    二叉树层序遍历
    栈的压入 弹出序列
    包含 min的栈
  • 原文地址:https://www.cnblogs.com/findumars/p/4973174.html
Copyright © 2011-2022 走看看