Qt之事件系统

发布时间 2023-05-22 15:10:08作者: 青衣守旧人

  Qt中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等。常见的处理事件的方法如下:

(1).重新实现部件的paintEvent、mousePressEvent()等事件处理函数,这是最常用的一种方法,不过只能用来出来特定部件的特定事件。

(2).重新实现event()函数,QObject类的event()函数可以在事件到达默认的事件处理函数之前获取该事件。

(3).在对象上安装事件过滤器,使用事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。

一、重写keyPressEvent函数

#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H

#include <QLineEdit>

class MyLineEdit : public QLineEdit
{
    Q_OBJECT
public:
    explicit MyLineEdit(QWidget *parent = nullptr);

protected:
    void keyPressEvent(QKeyEvent *event) override;

};

#endif // MYLINEEDIT_H
#include "my_lineedit.h"

#include <QKeyEvent>
#include <QDebug>

MyLineEdit::MyLineEdit(QWidget *parent) : QLineEdit(parent)
{

}

void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "MyLineEdit键盘按下事件";
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtWidgets>

class MyLineEdit;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QMainWindow *parent = nullptr);
    ~MainWindow();

protected:
    void keyPressEvent(QKeyEvent *event) override;

private:
    MyLineEdit *m_pLineEdit;
};
#endif // MAINWINDOW_H
#include "main_window.h"
#include "my_lineedit.h"

#include <QKeyEvent>
#include <QDebug>

MainWindow::MainWindow(QMainWindow *parent)
    : QMainWindow(parent),m_pLineEdit(new MyLineEdit(this))
{
    this->setFixedSize(600, 400);
    m_pLineEdit->move(100, 100);
}

MainWindow::~MainWindow()
{
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "MainWindow键盘按下事件";
}

这里自定义了一个MyLineEdit类,它继承自QLineEdit类,然后在MainWindow界面中添加一个MyLineEdit部件,这里既实现了MyLineEdit类的键盘按下事件处理函数,也实现了MainWindow类的键盘按键事件的处理函数,随意按下键盘的按键,只会打印"MyLineEdit键盘按下事件",说明这时只执行了MyLineEdit类中的keyPressEvent()函数。

下面在MyLineEdit类中的keyPressEvent()函数最后添加如下一行代码,让其忽略掉这个事件

event->ignore(); //忽略该事件

这时如果在按下按键,则会打印"MyLineEdit键盘按下事件"和"MainWindow键盘按下事件",但是这时却输入框中却无法输入任何字符,为了可以在输入框中正常输入字符,还需要添加下面一行代码:

void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "MyLineEdit键盘按下事件";

    QLineEdit::keyPressEvent(event); //执行QLineEdit类的默认事件处理
    event->ignore(); //忽略该事件
}

从上述例子可以看出,事件是先传递给指定窗口部件的,确切的说应该是先传递给获得焦点的窗口部件,但是如果该部件忽略掉该事件,那么这个事件就会传递给这个部件的父部件。重新实现事件处理函数时,一般要调用父类的相应事件处理函数来实现默认操作。