自己做整个网站的流程,php装修网站源码,长沙微网站建设,wordpress 不登陆后台 数据库恢复一、问题 前两篇文章写了很多有关桌面画板的实现方法#xff0c;这个过程中#xff0c;画笔的卡顿问题还是无法彻底解决。 先简单回顾一下我实现桌面画板的逻辑#xff1b; 1.父窗口#xff1a;一个透明窗口#xff0c;通过设置带有透明度的QColor bg_color#xff0c;以…一、问题 前两篇文章写了很多有关桌面画板的实现方法这个过程中画笔的卡顿问题还是无法彻底解决。 先简单回顾一下我实现桌面画板的逻辑 1.父窗口一个透明窗口通过设置带有透明度的QColor bg_color以及在paintEvent中整个窗口刷透明颜色。通过切换bg_color的alpha通道来实现画布的穿透效果或透明绘制效果没有透明度的白色则为白板。 QPainter painter(this);painter.fillRect(this-rect(), bg_color);2.绘图子窗口布局在父窗口内完全透明主要负责实际产生的QImage图像的刷新。 在该窗口中重载了相应的鼠标函数通过搜集一系列的鼠标经过点来对QImage进行绘制。有关QPainter绘制QImage的内容不再赘述。最后在该类的paintEvent中将整张QImage刷新上去实现绘制效果。 为了实现实时的刷新有两种思路。 1在moveEvent搜集点绘制QImage的同时update()触发paintEvent 2通过定时器每30ms刷新一次update将QImage绘制上去。这基本上是主流相机的图片帧帧率了 在我电脑上统计每一秒会触发900余次moveevent相当于搜集了900多个点。在进行临近点的过滤后仍然有500余点即会触发500次update因为update不是实时刷新内部有优化所以实际上不是这么多。这样的话paintEvent过于频繁在内部产生的耗时会造成moveEvent触发过少导致绘图卡顿是恶性循环。所以第二种方法较好。
可即便如此采用定时器触发在触发定时时仍会造成moveEvent的阻塞造成规律性的绘图卡顿即期望通过鼠标绘制一条圆滑曲线结果线段会规律地出现折线。
二、问题查找过程 通过繁琐的检测耗时我发现在moveEvent中对QImage实时绘制线段其实是极低的因为绘制刷新区域仅线段所在的范围 而在paintEvent中将一整张图绘制上窗口时耗时比较严重有25ms左右。 我又对比了QPixmap和QImage之间的效率发现相差不大又在窗口内塞入了一个QLabel想要另辟蹊径结果都不理想 最终我发现了造成25ms延时的问题所在子窗口触发paintEvent的同时父窗口也会触发paintEvent即我每一次刷新我的QImage图像时都还会让父窗口刷一遍半透明像素颜色… 通过检测耗时确定就是该处造成的原因
三、问题分析与解决办法 如果父窗口不是透明的速度立马上来了曲线变得圆滑简直完美可无奈我需要半透明画板因为我要实现桌面画板对ppt啊啥的进行实时标注嘛。 这就很让人头疼因为尝试了其他半透明窗口的实现都不理想。于是我想到了干脆不要父窗口了在子窗口中半透明像素的刷新和QImage的显示同步在paintEvent中做…… 结果就是跟之前是一毛一样的效果都是卡 而如果强行把半透明刷新和QImage拆开可能会造成一些奇怪的问题比如单次绘制之后因为没有触发半透明刷新导致窗口直接穿透了的bug
需要明确半透明像素颜色刷新是必须的。但我思考了下其实不需要全部刷新即不需要整个窗口区域的刷新。qt的update非常友好地提供了区域刷新的功能即
update(QRect(x,x,x,x));刷新的时候我直接传入一个计算好的矩形即可避免上述25ms耗时的产生。 是不是茅塞顿开hh 不过我还是采用了上述在子窗口中同时刷新半透明像素点和QImage的方法然后将父窗口直接完全透明处理了。 那剩下的就是刷新区域的计算问题了。 刷新半透明像素点本质上也是刷新QImage所以QRect的区域在我们moveEvent中采集点的过程中实时去计算目的是将“本次update的线段”都包含在QRect中。 因为考虑线宽的问题实际上QRect还要再往外扩一下详细代码就不贴了。 因为update传递了坐标所以系统优化的时候不会平白无故忽略了某一次造成有其中一次线段不显示的情况。
至此这个困扰我依旧的问题终于解决。效果嘛算是比较流畅了。