分享

Qt事件和事件过滤器

 t涂鸦 2012-02-21

在QT中,事件是一个继承QEvent的对象。事件通过调用QObject::event()方法被分发到继承自QObject的对象。事件分发意味着事件已经发生了,QEvent精确的指出QObject需要作何反应。大多数的事件被指定到QWidge及他的子类,但是也有很重要的事件不依赖于图形而发生,例如,socket激活,事件被QSocketNotifier利用进行工作。

一些事件来自视窗系统,例如:QMouseEvent,一些来自其他源,例如:QTimerEvent,还有一些来自于应用程序。通常Qt是对称的,所以你可以发送事件用相同的方法向QT自己的事件循环那样。

大多数的事件类型有指定的类,最常用的,QResizeEvent,QPaintEvent,QMouseEvent,QKeyEvent和QCloseEvent.也有其他的,大约有四十个左右,但是都很少用到。

每一个类子类QEvent并且增加指定事件的函数;注意啦,例如,QResizeEvent。在QResizeEvent的情况下,QResizeEvent:size()和QResizeEvent:oldSize()被添加。

一些类支持超过一种事件类型。QMouseEvent支持鼠标move,presses,shift-presses,drags,clicks,right-presses等等

因为程序需要反应于多变的和复杂的方式,Qt的事件分发技术是灵活的。QApplication::notify()的文档简明的描述了这整个过程,这里我们将充分的解释99%的应用。

一个事件被分发的通常的方法是通过调用一个虚函数。例如,QPaintEvent通过调用QWidget::paintEvent()被分发。这个虚函数负责正确的响应,重新绘画这个widget.

有时候不存在那样的一个特定的事件函数,或者特定的那个函数不能充分的满足需求。最通常的例子是tab键的press动作,它通常被QWidget认为是移动键盘的焦点,但是一些widgets本身需要TAB键。

这些对象能重新实现QObject::event(),通常的事件处理方法,在通常的处理事件的前后做他们的事件处理,或者完全代替它。一个非常不寻常的widget既解释tab又有一个指定应用的自定义事件可能包含:

 

  1. bool MyClass:event( QEvent * e ) {   
  2. if ( e->type() == QEvent::KeyPress ) {   
  3. QKeyEvent * ke = (QKeyEvent*) e;   
  4. if ( ke->key() == Key_Tab ) {   
  5. // special tab handling here   
  6. k->accept();   
  7. return TRUE;   
  8. }   
  9. else if ( e->type() >= QEvent::User ) {   
  10. QCustomEvent * c = (QCustomEvent*) e;   
  11. // custom event handling here   
  12. return TRUE;   
  13. }   
  14. QWidget::event( e );   
  15. }   


更一般的,一个对象需要监视另外的事件。Qt支持它通过QObject::installEventFilter()(和相应的去除动作)。例如,对话框对于一些widget想过滤掉按键操作,举个例子,改变回车键处理。

事件过滤器开始处理事件在目标对象行动之前。过滤器的QObject::eventFilter()实现被调用,能接受或者丢弃过滤,允许或者拒绝事件的更进一步的处理。如果所有的事件过滤器允许更进一步的事件处理,事件将被发送到目标对象本身。如果他们中的一个停止处理,目标和任何后来的事件过滤器不能看到任何事件。

可以过滤整个应用的所有的事件,通过在QApplication中安装一个事件过滤器。QToolTip就是通过这种办法看到键盘和鼠标的所有活动。非常强大,但是这也降低了在整个应用中每个单一事件的分发速度,所以还是最好避免。

指定对象的过滤器被调用之前全局事件过滤器会被首先调用。

最后,许多应用想要生成和发送他们自己的事件。

生成一个内建类型的事件是非常简单的:生成相应类型的一个对象,然后调用QApplication::sendEvent()或者QApplication::postEvent()。

sendEvent()立刻处理事件--当sendEvent()返回的时候,(事件过滤器和)对象已经处理完了事件。对于许多的事件类有一个函数叫做isAccepted()将被调用告诉你是否事件已经被接受或被最后一个处理者丢弃

postEvent()投送事件到一个队列以备之后分发。下一次Qt的主事件循环运行的时候,分发所有的已经投送的事件,附带一些优化,比如,如果有几次resize事件将被紧缩成一个。对于相同的应用paint事件:QWidget::update()调用postEvent(),通过避免多次repaint减少闪烁加快速度。

postEvent()也经常用在对象初始化,因此已经投送的事件将不久被分发在对象初始化完成之后。

对于生成自定义类型的事件,你需要定义一个事件号,它必须要大于QEvent::User,为了传递你自定义事件的特征你可能需要子类QCustomEvent
详细的请看QCustomEvent的文档 

 

原文出处:

http://www./pc/pccon.php?id=10001922&nid=321320

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多