Qt的事件系统(笔记)

59 篇文章 1 订阅

事件系统

Qt 中,事件是派生自抽象 QEvent 类的对象,它们表示在应用程序内发生的事情或作为应用程序需要了解的外部活动的结果。事件可以被 QObject 子类的任何实例接收和处理

如何传递事件

当一个事件发生时,Qt 通过构造适当的 QEvent 子类的实例来创建一个事件对象来表示它,并通过调用其 event() 函数将其传递给 QObject 的特定实例(或其子类之一)。

该函数不处理事件本身;根据传递的事件类型,它为该特定类型的事件调用事件处理程序,并根据事件是被接受还是被忽略来发送响应。

事件类型

大多数事件类型都有特殊的类,特别是 QResizeEvent、QPaintEvent、QMouseEvent、QKeyEvent 和 QCloseEvent。每个类都是 QEvent 的子类

QCoreApplication::notify() 

向接收者发送事件:receiver->event(event)。 返回从接收者的事件处理程序返回的值。 请注意,对于发送到任何线程中的任何对象的所有事件,都会调用此函数。

事件处理程序

传递事件的正常方式是调用虚函数。例如,QPaintEvent 是通过调用 QWidget::paintEvent() 来传递的。这个虚函数负责做出适当的反应

例如,以下代码处理自定义复选框Widget上的鼠标左键单击,同时将所有其他按钮单击传递给基 QCheckBox 类:

void MyCheckBox::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        // handle left mouse button here
    } else {
        // pass on other buttons to base class
        QCheckBox::mousePressEvent(event);
    }
}


 

如果要替换基类的功能,则必须自己实现所有内容。但是,如果您只想扩展基类的功能,那么您可以实现您想要的并调用基类以获得您不想处理的任何情况的默认行为。

可以重新实现通用事件处理程序 QObject::event(),并且可以在通常的处理之前或之后进行它们的事件处理,或者它们可以完全替换该函数。

bool MyWidget::event(QEvent *event)
{
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_Tab) {
            // special tab handling here
            return true;
        }
    } else if (event->type() == MyCustomEventType) {
        MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event);
        // custom event handling here
        return true;
    }

    return QWidget::event(event);
}

请注意,对于所有未处理的情况,仍然会调用 QWidget::event(),并且返回值指示是否处理了事件;真值可防止将事件发送到其他对象。


 

事件过滤器

有时,一个对象需要查看并可能拦截传递给另一个对象的事件。

QObject::installEventFilter() 函数通过设置事件过滤器来实现这一点,使指定的过滤器对象在其 QObject::eventFilter() 函数中接收目标对象的事件。

当调用过滤器对象的 eventFilter() 实现时,它可以接受或拒绝事件,并允许或拒绝对事件的进一步处理。如果所有事件过滤器都允许对事件进行进一步处理(每个都返回 false),则该事件将被发送到目标对象本身。如果其中一个停止处理(通过返回 true),则目标和任何后续事件过滤器根本看不到该事件。

bool FilterObject::eventFilter(QObject *object, QEvent *event)
{
    if (object == target && event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_Tab) {
            // Special tab handling
            return true;
        } else
            return false;
    }
    return false;
}

上面的代码显示了另一种拦截发送到特定目标Widget的 Tab 键按下事件的方法。在这种情况下,过滤器会处理相关事件并返回 true 以阻止它们被进一步处理。所有其他事件都被忽略

还可以通过在 QApplication 或 QCoreApplication 对象上安装事件过滤器来过滤整个应用程序的所有事件。

发送事件

许多应用程序想要创建和发送自己的事件。您可以通过构造合适的事件对象并使用 QCoreApplication::sendEvent() 和 QCoreApplication::postEvent() 以与 Qt 自己的事件循环完全相同的方式发送事件。

sendEvent() 立即处理事件。

postEvent() 将事件发布到队列中以供以后调度。

可以重新实现通用事件处理程序 QObject::event(),并且可以在通常的处理之前或之后进行它们的事件处理,或者它们可以完全替换该函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天进步2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值