Qt イベント システム: Qt でのイベント処理と配信

1. はじめに

Qt におけるイベントとは、QEvent クラスを継承したオブジェクトであり、一般的なものとしては、キーボードイベント QKeyEvent、マウスイベント QMouseEvent、タイマーイベント QTimerEvent などが挙げられます。この章では、これら 3 つの一般的なイベントについて詳しく説明し、イベント フィルターとカスタム イベントの知識も含みます。この章の関連内容については、Qt ヘルプのキーワード「イベント システム」から参照できます。

 

2. Qt のイベント

イベントとは、さまざまなアプリケーションによって内部または外部で生成され、知る必要があるイベントまたはアクションの総称です。オブジェクトは Qt でイベントを表すために使用され、QEvent クラスから継承されます。

イベントはシグナルと同じではないことに注意してください。たとえば、インターフェイス上のボタンをクリックすると、マウス イベント QMouseEvent (ボタンによって生成されるものではありません) が生成され、ボタンが押されると、それが送信されます。 out clicked() クリック信号 (ボタンによって生成される)。一般に、ここではボタンのクリック信号のみが考慮され、マウス イベントは考慮されませんが、ボタンをデザインする場合、またはボタンがクリックされたときに他の効果を生成するようにする場合は、マウス イベントを考慮する必要があります。 。イベントとシグナルは、異なる送信者と異なる機能を備えた 2 つの異なるレベルのものであることがわかります。Qt では、どの QObject サブクラス インスタンスもイベントを受信して​​処理できます。

2.1 イベント処理

イベントは特定の QEvent サブクラスによって表されますが、イベントには複数のイベント タイプが含まれる場合があります。たとえば、マウス イベントは、マウスを押す、ダブルクリック、移動などの複数の操作に分割できます。これらのイベント タイプは、QEvent クラスの列挙型 QEvent::Type によって表されます。これには 100 を超えるイベント タイプが含まれており、QEvent クラスのヘルプ ドキュメントで参照できます。QEvent のサブクラスはイベントを表すことはできますが、イベントの処理に使用することはできません。では、イベントはどのように処理されるべきでしょうか? QCoreApplication クラスの Notice() 関数のヘルプ ドキュメントには、イベントを処理する 5 つのメソッドが示されています。

  • 方法1: コンポーネントのpaintEvent()やmousePressEvent()などのイベント処理関数を再実装します。これは最も一般的に使用される方法ですが、特定のコンポーネントの特定のイベントを処理するためにのみ使用できます。
  • 方法 2:notify() 関数を再実装します。この関数は強力で、イベント フィルターがイベントを取得する前にイベントを取得するための完全な制御を提供します。ただし、一度に処理できるイベントは 1 つだけです。
  • 方法 3: QApplication オブジェクトにイベント フィルターをインストールします。プログラムにはQApplicationオブジェクトが1つしかないため、この方法で実現される機能はnotify()関数を使用するのと同じであり、複数のイベントを同時に処理できるという利点があります。
  • 方法 4:event() 関数を再実装します。QObject クラスのevent() 関数は、デフォルトのイベントハンドラーに到達する前にイベントを取得できます。
  • 方法 5: オブジェクトにイベント フィルターをインストールします。イベント フィルターを使用すると、1 つのインターフェイス クラス内のさまざまなサブコンポーネントのさまざまなイベントを同時に処理できます。

実際のプログラミングでは、方法 1 が最もよく使用され、次に方法 5 が使用されます。2 番目のメソッドは QApplication クラスから継承する必要があり、3 番目のメソッドはグローバル イベント フィルターを使用する必要があるため、イベントの送信が遅くなるため、これら 2 つのメソッドは非常に強力ですが、ほとんど使用されません。

この記事の利点は、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()関数の演算結果を返します。

widget.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() 関数の宣言もここに追加されます。

widget.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