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

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

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

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

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

  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. };

函数实现

  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. }

定义视图

  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函数

  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

Qt使用QGraphicsView实现滑动窗体效果的更多相关文章

  1. animate 实现滑动切换效果

    今天和大家分享一下用 animate 实现滑动切换效果的小例子 ------- 来自<一只有梦想的前端小白> 大家都知道jQuery 提供的有一下几种方法能够实现滑动效果: slideDo ...

  2. Android实现滑动刻度尺效果,选择身高体重和生日

    刻度尺效果虽然看起来很美,我个人认为很不实用,即使再不实用,也有用的,鉴于群里成员对我的苦苦哀求,我就分享一个他用不到的,横屏滑动刻度尺,因为他需要竖屏的,哈哈…… 最近群里的开发人员咨询怎样实现刻度 ...

  3. Android UI效果实现——Activity滑动退出效果

    更新说明: 1.在QQ网友北京-旭的提醒下,在SlideFrame的initilize方法中添加了focusable.focusableInTouch.clickable的状态设置,否则会导致部分情况 ...

  4. iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果

    8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...

  5. 【转】Android 实现ListView的滑动删除效果

    http://www.cnblogs.com/weixiao870428/p/3524055.html http://download.csdn.net/download/love_javc_you/ ...

  6. Android实现左右滑动指引效果

    本文介绍Android中实现左右滑动的指引效果. 关于左右滑动效果,我在以前的一篇博文中提到过,有兴趣的朋友可以查看:http://www.cnblogs.com/hanyonglu/archive/ ...

  7. 个人学习JQ插件编写成果:little酷炫的图片滑动切换效果

    工作一个多月了,好久没来冒冒泡了,看了@wayong的JQ插件教程,自己编写了一个模仿拉勾网首页广告栏滑动特效的JQ插件,现在跟朋友们分享分享! 先上demo链接:http://runjs.cn/de ...

  8. [Android] Android 类似今日头条顶部的TabLayout 滑动标签栏 效果

    APP市场中大多数新闻App都有导航菜单,导航菜单是一组标签的集合,在新闻客户端中,每个标签标示一个新闻类别,对应下面ViewPager控件的一个分页面,今日头条, 网易新闻等. 本文主要讲的是用:T ...

  9. 基于vue项目的组件中导入mui框架初始化滑动等效果时需移除严格模式的问题

    基于vue项目的组件中导入mui框架初始化滑动等效果时,控制台报错:Uncaught TypeError: 'caller', 'callee', and 'arguments' properties ...

随机推荐

  1. centos7编译安装MySQL5.7.9

    title: centos7编译安装MySQL5.7.9 date: 2016-05-12 16:20:17 tags: --- Centos7编译安装mysql5.7.9 mysql5.7有更好的性 ...

  2. Java线程同步与死锁认识

    讲下自己的认识,算小小的总结吧! synchroized 具有同步线程的功能,它的处理机制类似于给参数里面的对象赋一个标记值,来表明当前状态,当程序里面某个线程执行synchroized里面的代码段时 ...

  3. jQuery animate easing使用方法

    从jQuery API 文档中可以知道,jQuery自定义动画的函数.animate( properties [, duration] [, easing] [, complete] )有四个参数: ...

  4. (转)url重写

    使用URLRewriter.dll后,根本不需要使用任何代码,我之前做的项目就是用的做URL重写的,其实不是进化,其实表面上看是.html扩展名而已,当然你还可以用其他的任意扩展名下面是你的配置 &l ...

  5. Java 测试Hibernate+Mysql简单的数据存储

    想使用Hibernate框架,在网上看了一个Hibernate学习视频,试着做了一个小小的Java连接数据库的操作,Java初学者一个,大家多多包涵 开发环境: 1.安装MySql, 2.安装了Ecl ...

  6. SSH Secure Shell Client连接Linux 命令行显示中文乱码问题 和oracle 查询数据中文乱码问题

    一.SSH Secure Shell Client连接Linux 命令行显示中文乱码问题 linux 设置系统语言 修改 /etc/sysconfig/i18n 文件,如 LANG="en_ ...

  7. Swift - IBOutlet返回nil(fatal error: unexpectedly found nil while unwrapping an Optional value)

    在Swift 中 ViewController 默认构造方法不关联同名的xib文件 在使用OC的时候,调用ViewController的默认构造函数,会自动关联到一个与ViewController名字 ...

  8. [C#] 常用函数

    查找字符串: string test="a,b,c,de"; 方法1:Contains test.Contains("b")  //返回值 true 方法2:E ...

  9. JSP Servlet SQL 三者之间数据传递

    前言: 最近一直在做WEB开发,现总结一下这一段时间的体会和感触. 切记,web开发重点在于前台数据交互,页面美化而不要太沉溺于底层数据. 浏览器时代来到,向我们召唤出更炫.更简洁.更方便.更大气的网 ...

  10. Servlet 技术全总结 (已完成,不定期增加内容)

    Servlet是独立于平台和协议的服务器端的java应用程序,处理请求的信息并将其发送到客户端. Servlet的客户端可以提出请求并动态获得响应. Servlet动态生成web页面,担当浏览器或其他 ...