Qt使用QGraphicsView实现滑动窗体效果

来源:互联网 发布:linux 得到当前时间 编辑:程序博客网 时间:2024/06/05 02:51

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

 

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

 

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

 

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

 

 

 

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

 

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

[cpp] view plain copy
  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 plain copy
  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 plain copy
  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 plain copy
  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. }  
 

 

效果图




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

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小电充电宝丢失怎么办 qq连续聊天断了怎么办 胚胎怀疑在切口处怎么办 3D渲染没有材质怎么办 员工拒绝签收员工手册怎么办 二级密码错了三次怎么办 棉签掉到耳朵里怎么办 发财树叶子有黄斑怎么办 翠兰的颈枯萎了怎么办 翠兰主干软了怎么办 花叶子长白色粘粉末怎么办 水培转土培栀子花叶子蔫了怎么办 水冷空调水不循环怎么办 哺乳期乳房一个大一个小怎么办 我喝酒后喂奶了怎么办 磁盘目录不具有读写权限怎么办 玻纤网格布扎手怎么办 模拟城市5细菌太多怎么办 空气风犁叶子卷怎么办 晚上腿比早上粗怎么办 新疆公安边防改革新兵怎么办 专升本没有考上怎么办 摩托车漏检了2年怎么办 19年北京外地车怎么办 汽车遥控钥匙按键坏了怎么办 长安逸动噪音大怎么办 微信设置密码参数错误怎么办 太阳能电加热不加热怎么办 没报到换了工作怎么办 大学最后一年入伍入伍毕业证怎么办 当官不为民做主怎么办 去青海高反了怎么办 地暖地板低于客厅地面怎么办 9万月3分利息怎么办 免维护电瓶亏电怎么办 自煮小火锅吃完怎么办 孕囊形状是扁的怎么办 老公去世房产转到老婆手续怎么办 宝宝一周岁隔奶不喝牛奶怎么办 高中生偷买手机家长怎么办 丈夫迷上打麻将妻子该怎么办