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

2023-11-13

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

 

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

 

效果图




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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • SSH 和 SSL 加密协议

    SSH和SSL都是加密协议 用于保护网络通信的安全性和完整性 但它们用途和实现方式有所不同 SSH Secure Shell 是一种网络协议 用于远程访问和管理服务器 它提供了加密的连接和认证机制 使得数据传输更加安全 SSH通常用于远程登
  • Linux下使用STM32CUBEMX的makefile,报multiple defination错误的解决办法

    之所以报这个错是因为stm32cubemx生成makefile的一个bug 在C SOURCES部分会重复添加Src 下的c文件 上图是没有修改makefile之前 下图为修改后 要修改的部分
  • pthon代码实现在linux下对siebel服务器换包重启

    siebel服务器的换包重启 需要输入多个命令 而且中间需要等待 经常停了服务忘了启动 之前项目的TA有写过一些shell脚本 启服务的 停服务的 包括自动换包重启的 但是因为里面有个mount目录经常出问题 所以平时也没有使用 最近刚好在
  • css基本语法

    1 background background image url image jpg background color ccf background position center background repeat no repeat
  • 数据库:什么是主键

    数据库主键 主键 表中经常有一个列或列的组合 其值能唯一地标识表中的每一行 通俗叫 一个表中只能有一个主键 不接受空值 能唯一的表示表中的每一行 例如 银行卡的卡号就是主键 不存在重复的情况

随机推荐

  • Java 数据类型转换(Casting)

    Java中 经常可以遇到类型转换的场景 从变量的定义到复制 数值变量的计算到方法的参数传递 基类与派生类间的造型等 随处可见类型转换的身影 Java中的类型转换在Java编码中具有重要的作用 本文主要介绍一下Java 数据类型转换 Cast
  • 华为防火墙默认密码是什么?

    华为默认密码是什么 分享至 小王邀请您加入牛B的IT关键业务推动者社区 点击领取12G的软考 PMP资料包 特训营名额 gt gt 售前工程师系列 教你写解决方案 gt gt ld11235813 荣誉会员 Rank 12Rank 12Ra
  • 华为动态pnat配置

  • 微软宣布IE9正式版发布日期

    微软上月曾透露会在3月14日于美国德克萨斯州奥斯汀市SXSW音乐电影节上举办一个庆祝派对 从那时起就有很多猜想 我们才曾猜测微软届时会正式发布IE9 今天 微软终于不再卖关子 3月14日 也就是下周一 微软将正式发布IE9 微软证实 美国太
  • TensorFlow之双隐含层多层感知器(MLP)

    程序改自上一篇博客 使用了双隐含层 第二层隐含层初始w需要和第一层类似 否则程序正确率一直在0 1左右 修改后的程序正确率也在98 左右 coding utf 8 from tensorflow examples tutorials mni
  • 整理一些windows的bat命令及语法

    ver 在DOS窗口下显示版本信息 winver 弹出一个窗口显示版本信息 内存大小 系统版本 补丁版本 计算机名 format 盘符 FS 类型 格式化磁盘 类型 FAT FAT32 NTFS 例 Format D FS NTFS md
  • python基础系列之元组

    元组应用场景 储存多个数据 但是这些数据不可修改 我们知道列表可以储存多个数据 但是数据可增加 修改 删除 这也是元组和列表不一样的地方 如何定义一个元组 多个数据元组 t1 10 20 30 单个数据元组 t2 10 注意在定义单个数据的
  • 常量表达式函数

    我们可以在函数返回类型前加入关键字constexpr来使其成为常量表达式函数 但并非所有的函数都有资格成为常量表达式函数 事实上 常量表达式函数的要求非常严格 总结如下 函数体只有单一的return返回语句 函数必须返回值 不能是void函
  • 合并排序-递归分治

    按我的想法 简单地说 合并排序的思路就是 先递归 后排序 include
  • Java中的运算符

    1 算术运算符 基本四则运算符 1 规则比较简单 需要注意的是除法 int int 的结果还是 int 要想结果中有小数需要使用 double 类型 0 不能用来做除数 2 在Java中 表示取余 不仅可以对 int 求模 也可以对 dou
  • Tomcat Server处理一个http请求的过程

    Tomcat Server处理一个http请求的过程 假设来自客户的请求为 http localhost 8080 wsota wsota index jsp 1 请求被发送到本机端口8080 被在那里侦听的Coyote HTTP 1 1
  • 爬虫逆向实战(13)-某课网登录

    一 数据接口分析 主页地址 某课网 1 抓包 通过抓包可以发现登录接口是user login 2 判断是否有加密参数 请求参数是否加密 通过查看 载荷 模块可以发现有一个password加密参数 还有一个browser key这个可以写死不
  • C++ Pat甲级1013 Battle Over Cities (25 分)(求图的连通分量dfs)

    1013 Battle Over Cities 25 分 It is vitally important to have all the cities connected by highways in a war If a city is
  • 数字SOC设计之低功耗设计入门(六)——门级电路低功耗设计优化

    三 门级电路低功耗设计优化 1 门级电路的功耗优化综述 门级电路的功耗优化 Gate Level Power Optimization 简称GLPO 是从已经映射的门级网表开始 对设计进行功耗的优化以满足功耗的约束 同时设计保持其性能 即满
  • 【STM32篇】驱动MXL90614红外测温模块

    本次实验使用的测温模块型号GY 906 DCC模块 测距为10cm左右 一 简介 MLX90614 是一款红外非接触温度计 TO 39 金属封装里同时集成了红外感应热电堆探测器芯片和信处理专用集成芯片 由于集成了低噪声放大器 17 位模数转
  • 文件读/写操作 import pickle

    文件写 开 文件变量 open 文件路径文件名 web 存 pickle dump 待写入的变量 文件变量 关 文件变量 close 文件读 开 文件变量 open 文件路径文件名 rb 取 放内容的变量 pickle load 文件变量
  • 小程序 -- 分包

    来源 1 什么是分包 分包指的是把一个完整的小程序项目 按照需求划分为不同的子包 在构建时打包成不同的分包 用户在使用时按需进行加载 2 分包的好处 对小程序进行分包的好处主要有以下两点 可以优化小程序首次启动的下载时间 在多团队共同开发时
  • 二叉树之层次遍历(js)

    二叉树之层次遍历 输入一棵二叉树 你的任务是从上到下 从左到右的顺序输出各个结点的值 每个结点都是按照从根节点到它移动序列给出 L表示左 R表示右 在输入中 每个结点的左右括号之间没有空格 相邻节点之间用一个空格隔开 输入 11 LL 7
  • GameFi 大爆发?五款令人期待的链游

    大家好 我是晴天defi 在今年 有许多游戏公司陆续推出自家的IP大作 像是任天堂出的宝可梦 阿尔宙斯 Sony 的地平线 西域禁地 Techland 的垂死之光 2 就连那位喜欢虐待玩家的宫崎英高 也跟着推出他的全新虐待新作 艾二登 法环
  • Qt使用QGraphicsView实现滑动窗体效果 .

    源码已上传至CSDN http download csdn net source 2808505 QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容 QGraphicsScene提供了QGraphicsIte