Qt中的事件(1)

原创
2022-11-25
4611
1

1. Qt的事件简介

Qt中提供了很多与外部设备交互的事件,如鼠标事件QMouseEvent,键盘事件QKeyEvent等。

Qt中事件的分发大概流程是这样的:

  1. QCoreApplication::notify函数。在Qt中事件都是QEvent的派生类的实例,所有QObject的派生类都可以处理事件。而事件在Qt框架中的起点就是QCoreApplication::notify函数。
  2. 应用过滤器。
  3. 对象过滤器。
  4. QObject::event()函数。
  5. 特定事件处理函数,如keyPressEvent()等。

2. 重写特定事件处理器

Qt可以针对特定事件添加自己想要的供能。

.h文件中的定义:

protected:
    virtual void mousePressEvent(QMouseEvent *event);

.cpp文件中的定义:

void Widget::mousePressEvent(QMouseEvent *event)
{
    int xPt = event->pos().x();
    int yPt = event->pos().y();
    qDebug() << "QWidget " << xPt << ", " << yPt;
    return QWidget::mousePressEvent(event);
}

3. 事件的传递和处理

一个事件,可以被接受(调用QEvent::accept()方法接受一个事件)或者忽略(调用QEvent::ignore()方法忽略一个事件)。被接受事件,不会投递给其他对象;被忽略的事件会被投递给其他可能关心这个事件的对象,直到有对象处理了它或者所有对象都表示不在乎它。

下面是一个事件传递的例子:

.h例子:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>

class PushButton : public QPushButton
{
    Q_OBJECT

public:
    PushButton(QWidget *parent = nullptr);
    ~PushButton();

protected:
    virtual void mousePressEvent(QMouseEvent *event);
};

// -----------------------------------------------------------------------------------
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

protected:
    virtual void mousePressEvent(QMouseEvent *event);

private:
    QPushButton *m_Button = nullptr;
};

#endif // WIDGET_H

.cpp例子:

#include "widget.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QMouseEvent>

PushButton::PushButton(QWidget *parent)
    :QPushButton(parent)
{
    this->setFixedSize(200, 200);
}

PushButton::~PushButton()
{

}

void PushButton::mousePressEvent(QMouseEvent *event)
{
    QPushButton::mousePressEvent(event);
    qDebug() << "MousePressed " << event->pos().x() << ", " << event->pos().y();
    event->ignore();
}

// -----------------------------------------------------------------------------------
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_Button = new PushButton(this);
    m_Button->setText("OK");

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(m_Button);

    QObject::connect(m_Button, &QPushButton::clicked, [=](void)->void{
       qDebug() << "PushButton Pressed!" ;
    });

    this->setGeometry(100, 100, 800, 600);
}

Widget::~Widget()
{

}

void Widget::mousePressEvent(QMouseEvent *event)
{
    int xPt = event->pos().x();
    int yPt = event->pos().y();
    qDebug() << "QWidget " << xPt << ", " << yPt;
    return QWidget::mousePressEvent(event);
}

点击按钮后的运行结果:
MousePressed 144 , 77
QWidget 157 , 277
PushButton Pressed!

QPushButton::mousePressEvent(event)默认会接收鼠标事件,按钮处理MousePress事件后,调用event->ignore()函数事件被忽略向下传递到Widget类中,Widget类处理mousePress事件。

不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:Qt中的事件(2)- 事件过滤器