• 5010阅读
  • 13回复

求助关于QGraphicsScene中SVGItem的刷新问题 [复制链接]

上一主题 下一主题
离线longkimari
 

只看楼主 倒序阅读 楼主  发表于: 2018-04-18
各位大师:

        我在做一个仪表类项目,用得是QGrahpicsScene。
        基本结构是这样的:
                
               m_scene ----->  textItem(位置不变、内容用Setplainttext来改变)、svgitem (位置不变,内容不变的框架)
                              |——> svgitem类(位置或内容需要变更的)
               通过timer控制m_scene.update ;
        
           在svgitem类中,用QSvgRenderer载入svg素材,用QSvgRenderer.setviewbox来确定显示素材的区域,render来渲染;
            整个重绘数据是一个全局数据结构;由一个UDP类提供更新;
            目前程序运行都是正常的,但是遇到一个问题
            在timer控制的scene.update执行后,svgitem类显示的内容没有根据数据更新;

            如果在强制在 scene.update前执行QGraphicsSVGItem.update进行更新,
            那么虽然运行正常了,但是刷新率下降到无法容忍的程度;

            希望各位大师能指明一个刷新的策略,解决这个问题;




==================================我是分割线===========================================


           另外,这次开发的项目是一个简单的仪表类项目;
           使用的svg素材并不多,udp我也放到了线程执行;理论上刷新率应该很高的;
           但是实际上刷新率才50+不到60;
           这是什么原因呢?


最后,先感谢参与讨论的各位,谢谢了。

离线maxlogo

只看该作者 1楼 发表于: 2018-04-19
刷新不要全部刷新,而仅是当item的boundingRect改变时才需要刷新, prepareGeometryChange 了解一下
1条评分威望+1
longkimari 威望 +1 - 2018-04-19
个人博客:
简书:https://www.jianshu.com/u/14fa805306bd
CSDN:https://blog.csdn.net/qq10097355
思否:https://segmentfault.com/u/lowbees/articles
离线大漠之鹰

只看该作者 2楼 发表于: 2018-04-19
什么平台?
硬件性能怎么样?
Qt4还是Qt5,有没有绘制加速?
界面刷新最好由数据驱动吧,哪些元素变化了更新哪些元素,定时器刷新你是全部刷新的吧?数据量偏大啊。应该是实时监测UDP数据,变化后发送信号给相关Item,Item做更新。
本是后山人,偶作前堂客,醉舞经阁半卷书,坐井说天阔。大志戏功名,海斗量福祸,论到囊中羞涩时,怒指乾坤错
QQ:874164244
离线longkimari

只看该作者 3楼 发表于: 2018-04-19
回 maxlogo 的帖子
maxlogo:刷新不要全部刷新,而仅是当item的boundingRect改变时才需要刷新, prepareGeometryChange 了解一下 (2018-04-19 09:22) 

item的boundingRect设定是不会改变的,但是其中的素材内容会变;这样是不是不会触发刷新?
离线longkimari

只看该作者 4楼 发表于: 2018-04-19
回 大漠之鹰 的帖子
大漠之鹰:什么平台?
硬件性能怎么样?
Qt4还是Qt5,有没有绘制加速?
界面刷新最好由数据驱动吧,哪些元素变化了更新哪些元素,定时器刷新你是全部刷新的吧?数据量偏大啊。应该是实时监测UDP数据,变化后发送信号给相关Item,Item做更新。 (2018-04-19 11:29) 

平台是WIN7 硬件性能绝对没问题
QT5,绘制加速没有特别去设置,怎么设置?
用的QGLWidget,初始化代码如下:
pWidget = new QGLWidget(QGLFormat(QGL::SampleBuffers));
    pWidget->resize(1024,768);
    resize(1024,768);
    move(440,0);

    m_scene= new QGraphicsScene;
    m_view= new QGraphicsView(this);
    m_view->setSceneRect(0,0,1024,768);
    m_view->setCacheMode(QGraphicsView::CacheBackground);
    m_view->setOptimizationFlags(QGraphicsView::DontSavePainterState);
    m_view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    m_view->setViewport(pWidget);
    m_view->setStyleSheet("border:none; background:transparent;");
    m_view->setScene(m_scene);
离线maxlogo

只看该作者 5楼 发表于: 2018-04-19
刷新应由item的update刷新,尽量避免整个scene的update
个人博客:
简书:https://www.jianshu.com/u/14fa805306bd
CSDN:https://blog.csdn.net/qq10097355
思否:https://segmentfault.com/u/lowbees/articles
离线longkimari

只看该作者 6楼 发表于: 2018-04-19
回 maxlogo 的帖子
maxlogo:刷新应由item的update刷新,尽量避免整个scene的update (2018-04-19 13:22) 

几个百个item逐个update?
离线longkimari

只看该作者 7楼 发表于: 2018-04-20
顶顶,别沉了
离线大漠之鹰

只看该作者 8楼 发表于: 2018-04-20
回 longkimari 的帖子
longkimari:几个百个item逐个update? (2018-04-19 19:13) 

不是逐个刷新,是谁变刷新谁。数据驱动,接收到数据,解析完成后,发送信号给对应的Item,让对应的Item执行update。如果没有任何变化,界面就保持静止。
1条评分好评度+1
longkimari 好评度 +1 - 2018-04-20
本是后山人,偶作前堂客,醉舞经阁半卷书,坐井说天阔。大志戏功名,海斗量福祸,论到囊中羞涩时,怒指乾坤错
QQ:874164244
离线longkimari

只看该作者 9楼 发表于: 2018-04-20
回 大漠之鹰 的帖子
大漠之鹰:不是逐个刷新,是谁变刷新谁。数据驱动,接收到数据,解析完成后,发送信号给对应的Item,让对应的Item执行update。如果没有任何变化,界面就保持静止。 (2018-04-20 16:59) 

非常感谢您的回答;
我的项目是仪表盘,基本上数据一来都会变化;
感觉逐个写UPDATE和整体刷新差不多;
另外今天在测试的时候发现,在加入某个item的update的时候,帧率大幅下降;
检查了item的paint函数,没有发现问题,懵逼中。。。。。
离线longkimari

只看该作者 10楼 发表于: 2018-04-23
跑了以下刷新的时间记录,发现每次刷新后,虽然按照信号槽设定timer(1)调用updateview,但是实际上是300~400毫秒后才开始刷新,这段时间系统干嘛去了呢?
离线大漠之鹰

只看该作者 11楼 发表于: 2018-04-23
回 longkimari 的帖子
longkimari:非常感谢您的回答;
我的项目是仪表盘,基本上数据一来都会变化;
感觉逐个写UPDATE和整体刷新差不多;
另外今天在测试的时候发现,在加入某个item的update的时候,帧率大幅下降;
....... (2018-04-20 23:45) 

你的帧率怎么计算啊?计算帧率想要做什么指标呢?
如果数据驱动的话,两帧数据之间没有数据变化帧率就是0;做这个不需要看帧率,关心你的CPU占用率就行了。CPU占用率越低越好;你提到的定时器刷新的方案,会让CPU负载过重,导致CPU无法及时响应你的定时器事件,所以才会出现你定时器时间不准的现象。
本是后山人,偶作前堂客,醉舞经阁半卷书,坐井说天阔。大志戏功名,海斗量福祸,论到囊中羞涩时,怒指乾坤错
QQ:874164244
离线longkimari

只看该作者 12楼 发表于: 2018-04-23
回 大漠之鹰 的帖子
大漠之鹰:你的帧率怎么计算啊?计算帧率想要做什么指标呢?
如果数据驱动的话,两帧数据之间没有数据变化帧率就是0;做这个不需要看帧率,关心你的CPU占用率就行了。CPU占用率越低越好;你提到的定时器刷新的方案,会让CPU负载过重,导致CPU无法及时响应你的定时器事件,所以才会出现你定 .. (2018-04-23 09:43) 

用fraps测定的
离线longkimari

只看该作者 13楼 发表于: 2018-04-23
今天输出了每个模块的时间,不知道刷新到刷新之间的时间用在什么地方了:
Count: 0 :initliaze done:const time: 827

main thread: 0x27d8
Count: 1 :refresh start!!!!: 68

from thread slot: 0x27bc
Count: 1 :updateText done:const time: 31

Count: 1 :updateADI done:const time: 0

Count: 1 :updateVEL_SCALE done:const time: 0

Count: 1 :updateVEL_num done:const time: 1

Count: 1 :updateVEL done:const time: 2

Count: 1 :updateALT_SCALE done:const time: 3

Count: 1 :updateALT_num done:const time: 0

Count: 1 :updateALT done:const time: 3

Count: 1 :updateHSI done:const time: 0

Count: 1 :All refresh work done!!!!: 3

Count: 2 :refresh start!!!!: 555            //这里从刷新完毕到刷新用了555毫秒,实际上我timer设定的是1毫秒

Count: 2 :updateText done:const time: 6

Count: 2 :updateADI done:const time: 0

Count: 2 :updateVEL_SCALE done:const time: 0

Count: 2 :updateVEL_num done:const time: 2

Count: 2 :updateVEL done:const time: 0

Count: 2 :updateALT_SCALE done:const time: 3

Count: 2 :updateALT_num done:const time: 0

Count: 2 :updateALT done:const time: 3

Count: 2 :updateHSI done:const time: 0

Count: 2 :All refresh work done!!!!: 2

Count: 3 :refresh start!!!!: 344

Count: 3 :updateText done:const time: 6

Count: 3 :updateADI done:const time: 0

Count: 3 :updateVEL_SCALE done:const time: 0

Count: 3 :updateVEL_num done:const time: 2

Count: 3 :updateVEL done:const time: 3

Count: 3 :updateALT_SCALE done:const time: 3

Count: 3 :updateALT_num done:const time: 2

Count: 3 :updateALT done:const time: 3

Count: 3 :updateHSI done:const time: 2

Count: 3 :All refresh work done!!!!: 2
快速回复
限100 字节
 
上一个 下一个