Qt 이벤트 시스템: Qt에서 이벤트 처리 및 전달

1. 소개

Qt에서 이벤트란 QEvent 클래스를 상속받은 객체로 일반적인 것으로는 키보드 이벤트 QKeyEvent, 마우스 이벤트 QMouseEvent, 타이머 이벤트 QTimerEvent 등이 있다. 이 장에서는 이러한 세 가지 일반적인 이벤트에 대해 자세히 설명하고 이벤트 필터 및 사용자 정의 이벤트에 대한 지식도 포함합니다. 이 장의 관련 내용은 Qt 도움말의 The Event System 키워드를 통해 볼 수 있습니다.

 

2. Qt의 이벤트

이벤트는 알려야 하는 다양한 응용 프로그램에 의해 내부 또는 외부에서 생성되는 이벤트 또는 작업에 대한 일반적인 용어입니다. 객체는 QEvent 클래스에서 상속된 이벤트를 나타내기 위해 Qt에서 사용됩니다.

이벤트는 시그널과 같지 않다는 점에 유의해야 하는데, 예를 들어 인터페이스에서 버튼을 클릭하면 마우스 이벤트 QMouseEvent(버튼에 의해 생성되지 않음)가 발생하고 버튼을 눌렀기 때문에 out clicked() 클릭 신호(버튼에 의해 생성됨). 일반적으로 여기에서는 버튼의 클릭 신호만 고려하고 마우스 이벤트는 고려하지 않지만 버튼을 디자인하거나 버튼을 클릭했을 때 다른 효과가 발생하도록 하려면 마우스 이벤트에 신경을 써야 합니다. . 이벤트와 신호는 발신자와 기능이 다른 두 가지 수준의 사물임을 알 수 있습니다. Qt에서 모든 QObject 하위 클래스 인스턴스는 이벤트를 수신하고 처리할 수 있습니다.

2.1 이벤트 처리

이벤트는 특정 QEvent 하위 클래스로 표시되지만 이벤트에는 여러 이벤트 유형이 포함되는 경우가 있습니다.예를 들어 마우스 이벤트는 마우스 누르기, 두 번 클릭 및 이동과 같은 여러 작업으로 나눌 수 있습니다. 이러한 이벤트 유형은 100개 이상의 이벤트 유형을 포함하는 QEvent 클래스의 열거 유형 QEvent::Type으로 표시되며 QEvent 클래스의 도움말 문서에서 볼 수 있습니다. QEvent의 서브클래스는 이벤트를 나타낼 수 있지만 이벤트를 처리하는 데 사용할 수 없으므로 이벤트를 어떻게 처리해야 합니까? QCoreApplication 클래스의 notify() 함수 도움말 문서에는 이벤트를 처리하는 다섯 가지 방법이 나와 있습니다.

  • 방법 1: 구성 요소의 paintEvent() 및 mousePressEvent()와 같은 이벤트 처리 기능을 다시 구현합니다. 이것은 가장 일반적으로 사용되는 방법이지만 특정 구성 요소의 특정 이벤트를 처리하는 데만 사용할 수 있습니다.
  • 방법 2: notify() 함수를 다시 구현합니다. 이 기능은 강력하며 이벤트 필터가 이벤트를 가져오기 전에 이벤트를 가져오는 완전한 제어를 제공합니다. 그러나 한 번에 하나의 이벤트만 처리할 수 있습니다.
  • 방법 3: QApplication 개체에 이벤트 필터를 설치합니다. 프로그램에는 QApplication 객체가 하나만 있기 때문에 이렇게 구현한 함수는 notify() 함수를 사용한 것과 동일하며 여러 이벤트를 동시에 처리할 수 있다는 장점이 있습니다.
  • 방법 4: event() 함수를 다시 구현합니다. QObject 클래스의 event() 함수는 기본 이벤트 핸들러에 도달하기 전에 이벤트를 가져올 수 있습니다.
  • 방법 5: 개체에 이벤트 필터를 설치합니다. 이벤트 필터는 동시에 하나의 인터페이스 클래스에서 서로 다른 하위 구성 요소의 서로 다른 이벤트를 처리하는 데 사용할 수 있습니다.

실제 프로그래밍에서는 방법 1이 가장 일반적으로 사용되며 그 다음이 방법 5입니다. 두 번째 방법은 QApplication 클래스에서 상속해야 하고 세 번째 방법은 전역 이벤트 필터를 사용해야 하므로 이벤트 전송 속도가 느려지므로 이 두 방법은 매우 강력하지만 거의 사용되지 않습니다.

이 기사의 이점, Qt 개발 학습 자료 패키지, 기술 비디오(C++ 언어 기초, Qt 프로그래밍 소개, QT 신호 및 슬롯 메커니즘, QT 인터페이스 개발-이미지 그리기, QT ​​네트워크, QT 데이터베이스 프로그래밍, QT 포함)를 무료로 받을 수 있습니다. 프로젝트 컴뱃, QSS, OpenCV, 퀵모듈, 면접질문 등) ↓↓↓↓↓↓아래 참조↓↓기사 하단을 클릭하시면 수수료를 받을 수 있습니다↓↓

2.2 이벤트 전달

각 프로그램의 main() 함수 끝에서 QApplication 클래스의 exec() 함수가 호출되어 Qt 응용 프로그램이 이벤트 루프에 진입하여 응용 프로그램이 런타임 중에 발생하는 다양한 이벤트를 수신할 수 있습니다. 이벤트가 발생하면 Qt는 해당 QEvent 하위 클래스 개체를 구성하여 이를 나타내는 다음 해당 QObject 개체 또는 해당 하위 개체에 전달합니다. 예제를 통해 Qt에서의 이벤트 전달 과정을 살펴보자 .

새 Qt Gui 응용 프로그램을 만들고 프로젝트 이름은 myEvent이고 기본 클래스는 QWidget이며 클래스 이름은 Widget으로 유지됩니다. 설정이 완료되면 프로젝트에 새 파일을 추가하고 C++ 클래스를 템플릿으로 선택하고 클래스 이름은 MyLineEdit이며 기본 클래스를 QLineEdit로 수동으로 채우고 MyLineEdit 클래스를 사용자 지정합니다.

mylineEdit.h 파일:

#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H

#include <QLineEdit>

class MyLineEdit : public QLineEdit
{
    Q_OBJECT
public:
    explicit MyLineEdit(QWidget *parent = nullptr);
    
    // event()函数获取事件的类型
	bool event(QEvent *event);    

protected:
    // MyLineEdit类的键盘按下事件
    void keyPressEvent(QKeyEvent *event);
};

#endif // MYLINEEDIT_H

keyPressEvent() 함수 및 event() 함수의 선언이 여기에 추가됩니다.

mylineEdit.cpp 파일:

#include "mylineedit.h"
#include <QKeyEvent>
#include <QDebug>

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

}

// MyLineEdit类的键盘按下事件
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
    qDebug() << tr("MyLineEdit键盘按下事件");
    // 让MyLineEdit输入栏能输入字符
    QLineEdit::keyPressEvent(event);          // 执行QLineEdit类的默认事件处理
    event->ignore();                          // 忽略该事件
}

//event()函数获取事件的类型
bool MyLineEdit::event(QEvent *event)  
{
    // 判断触发事件类型是否为键盘按下事件
    if(event->type() == QEvent::KeyPress)
        qDebug() << tr("MyLineEdit的event()函数");
    return QLineEdit::event(event);   // 执行QLineEdit类event()函数的默认操作
}

여기에서 QWidget을 상속하고 MyLineEdit 클래스의 keyPressEvent() 함수 및 event() 함수를 구현하는 MyLineEdit 클래스를 사용자 정의합니다. event() 함수는 event->type()을 사용하여 이벤트 유형을 가져옵니다. 키보드 누름 이벤트 QEvent::KeyPress이면 정보를 출력하고 부모 클래스의 event() 함수의 연산 결과를 반환합니다.

위젯.h 파일:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
class MyLineEdit;
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

	// Widget类的事件过滤器
    bool eventFilter(QObject *obj, QEvent *event);    

private:
    Ui::Widget *ui;
    MyLineEdit *lineEdit;

protected:
    // Widget类的键盘按下事件
    void keyPressEvent(QKeyEvent *event);
};

#endif // WIDGET_H

keyPressEvent() 함수의 선언도 여기에 추가됩니다.

위젯.cpp 파일:

#include "widget.h"
#include "ui_widget.h"
#include "mylineedit.h"
#include <QKeyEvent>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
        
    lineEdit = new MyLineEdit(this);
    lineEdit->move(100, 100);
}

Widget::~Widget()
{
    delete ui;
}

// Widget类的键盘按下事件
void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug() << tr("Widget键盘按下事件");
}

// Widget类的事件过滤器
bool Widget::eventFilter(QObject *obj, QEvent *event) // 事件过滤器
{
    // 如果是lineEdit部件上的事件
    if(obj == lineEdit)
    {              
        if(event->type() == QEvent::KeyPress)
            qDebug() << tr("Widget的事件过滤器");
    }
    return QWidget::eventFilter(obj, event);
}

Widget 클래스의 keyPressEvent() 함수도 여기서 구현되며 MyLineEdit 클래스의 keyPressEvent() 함수가 호출됩니다. 이벤트 필터에서 먼저 이벤트의 객체가 lineEdit인지 판단하고 그렇다면 이벤트 유형을 판단하고 마지막으로 QWidget 클래스의 기본 이벤트 필터 실행 결과를 반환합니다.

프로그램을 실행한 다음 키보드의 아무 키나 누릅니다. 예를 들어 여기에서 a 키를 누르면 실행 결과가 아래 그림에 표시됩니다.

 

이벤트 전달 순서는 다음과 같다는 것을 알 수 있다: 먼저 이벤트 필터, 다음으로 포커스 구성 요소의 event() 함수, 마지막으로 포커스 구성 요소의 이벤트 핸들러, 예를 들어 여기에서는 키보드 누르기 이벤트 함수; 포커스 컴포넌트가 이벤트를 무시하면 위 그림과 같이 상위 컴포넌트의 이벤트 처리 기능이 실행됩니다. event() 함수와 이벤트 처리 함수는 구성 요소 내에서 재정의되고 이벤트 필터는 구성 요소의 상위 구성 요소에서 정의됩니다.

이 기사의 이점, Qt 개발 학습 자료 패키지, 기술 비디오(C++ 언어 기초, Qt 프로그래밍 소개, QT 신호 및 슬롯 메커니즘, QT 인터페이스 개발-이미지 그리기, QT ​​네트워크, QT 데이터베이스 프로그래밍, QT 포함)를 무료로 받을 수 있습니다. 프로젝트 컴뱃, QSS, OpenCV, 퀵모듈, 면접질문 등) ↓↓↓↓↓↓아래 참조↓↓기사 하단을 클릭하시면 수수료를 받을 수 있습니다↓↓ 

추천

출처blog.csdn.net/QtCompany/article/details/131743397