https://software.intel.com/zh-cn/blogs/2011/05/24/qt/
经过一个星期的项目初步开发,写此文就开发时遇到的一些常见问题,给出些资料和自己的观点,希望能给其他的初学者或者参赛的选手一点帮助,当然,也算是一种抛砖引玉,大家有什么好的技巧经验什么的,也能多多分享,借助这次比赛,我们共同进步~
如果大家都是跟我一样,刚刚开始接触QT,开始开发QT的程序,肯定也会有很多不习惯的地方,今天我重点想谈的就是这么一个不习惯的地方--QT中窗口刷新事件。
对于窗体刷新事件,我主要谈一下paintevent的使用,我猜也许很多人初次使用这个的时候,也跟我一样一头雾水,搞不懂这个是在什么时候被调用的,现在我来简单说明一下。
void QWidget::paintEvent ( QPaintEvent * )
如果不了解它的原理,任意找个例子程序你也是很难找到什么时候它被调用的痕迹的。
Paint这个事件只要是窗体部件需要被重绘了就会被调用,是由窗体系统产生的,但要求程序重画窗体部件的时候,事件循环就会从事件队列里面选中这个事件并把它分发到那个需要重画的widget中。并不是所有的paint事件都是由窗口系统产生的,通过repaint()或update()你也可以使用它。但是,需要知道的是,就算你很不耐烦,想直接调用paintEvent(),这是不可能的,因为paintEvent()函数是protected的(很可能访问不了)。它也绕开了任何存在的事件过滤器。因为这些原因,Qt提供了一个机制,直接sending事件而不是posting 。
不过,需要注意的是,有时候update()执行后不一定会直接转到paintEvent。为什么会这样?这是因为QT会把多个绘制事件自动的合并成一个来加快绘制速度。这一点,是不是也很不习惯呢,不过,我认为也是很有优势的一点,在实现我们的程序的时候,我们可以把所有的绘制窗体的那些语句函数什么的都放到paintEvent,通过各种如 if-else语句进行判断来绘制,这样对速度有很好的优化并且可以防止闪烁。
绘制事件还有一点也很需要注意,那就是:当绘制事件发生的时候,更新区域通常被擦除。如果需要在上次绘制的基础上进行绘制的话,我的做法是:用一个临时变量存着上次绘制后的图,然后在这个图上进行绘制,最后再直接显示这个图就行了。是个很笨的方法,如果大家有其他的更好的方法可以接受下。顺便提一下,通过QPaintEvent::erased()可以得知这个窗口部件是否被擦除。
Ps:写完查了一下,在WRepaintNoErase窗口部件标记被设置的时候不会擦除。
void QWidget::update ()
这个事件上文中就提到了,用于更新窗体部件,它规划了所要处理的绘制事件。可以被QT优化,把多个绘制事件合并。所以推荐大家使用这个,而不是repaint()。几次调用update()的结果通常仅仅是一次paintEvent()调用,这个优化对性能还是很有好处的。
今天就介绍这么多,都是些基础的东西。大牛们就不用看了,呵呵,希望和我一样的初学者们,也都能介绍下自己开发中遇到的问题,大家一起分享讨论进步。