Qt的事件系统

事件系统

在 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(),并且可以在通常的处理之前或之后进行它们的事件处理,或者它们可以完全替换该函数。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

猜你喜欢

转载自blog.csdn.net/m0_73443478/article/details/132583838