分类: 嵌入式
2013-12-19 11:31:31
事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。
在 Qt 中,事件的概念似乎同信号槽类似。的确如此,一般来说,使用 Qt 组件时,我们并不会把主要精力放在事件上。因为在 Qt 中,我们关心的更多的是事件关联的一个信号。比如,对于QPushButton的鼠标点击,我们不需要关心这个鼠标点击事件,而是关心它的clicked()信号的发出。
但是,Qt 中的事件和信号槽却并不是可以相互替代的。信号由具体的对象发出,然后会马上交给由connect()函数连接的槽进行处理;而对于事件,Qt 使用一个事件队列对所有发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部。前一个事件完成后,取出后面的事件进行处理。但是,必要的时候,Qt 的事件也可以不进入事件队列,而是直接处理。信号一旦发出,对应的槽函数一定会被执行。但是,事件则可以使用“事件过滤器”进行过滤,对于有些事件进行额外的处理,另外的事件则不关心。
Qt 程序需要在main()函数创建一个QCoreApplication对象,然后调用它的exec()函数。这个函数就是开始 Qt 的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler)。
在所有组件的父类QWidget中,定义了很多事件处理的回调函数,如keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent()、mousePressEvent()、mouseReleaseEvent()等。这些函数都是 protected virtual 的,也就是说,我们可以在子类中重新实现这些函数。
我们可以在子类中重新实现这些函数。下面来看一个例子:
点击(此处)折叠或打开
我们重写了CustomButton的mousePressEvent()函数,也就是鼠标按下。在这个函数中,我们判断如果鼠标按下的是左键,则打印出来“left”字符串,否则,调用父类的同名函数。
当重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行!比如我们的CustomButton了,如果像我们这么覆盖函数,clicked()信号永远不会发生,你连接到这个信号的槽函数也就永远不会被执行。这个错误非常隐蔽,很可能会浪费你很多时间才能找到。因为这个错误不会有任何提示。这一定程度上说,我们的组件“忽略”了父类的事件,但这更多的是一种违心之举,一种错误。
返回目录:Qt学习整理