「Qtのコントロール - キーボード」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
3行目: 3行目:
<br><br>
<br><br>


== キーボード入力 ==
== 単一キーの取得 ==
フォーカスを持つオブジェクトに破棄されたイベントは、<code>keyPressEvent</code>メソッドで受け取れない。<br>
フォーカスを持つオブジェクトに破棄されたイベントは、<code>keyPressEvent</code>メソッドで受け取れない。<br>
イベント一括処理で破棄されたイベントは受け取れない。<br>
イベント一括処理で破棄されたイベントは受け取れない。<br>

2021年3月30日 (火) 12:52時点における版

概要



単一キーの取得

フォーカスを持つオブジェクトに破棄されたイベントは、keyPressEventメソッドで受け取れない。
イベント一括処理で破棄されたイベントは受け取れない。

 // Mainwindow.h
 
 // ...略
 
 protected:
    void keyPressEvent(QKeyEvent *pEvent);


 // Mainwindow.cpp
 
 // 押下したキー名をデバッグ出力する
 // その他のキーは、16進数を出力する
 void MainWindow::keyPressEvent(QKeyEvent *pEvent)
 {
    switch (pEvent->key())
    {
       case Qt::Key_Escape:
          qDebug() << "Esc keyPress";
          break;
       case Qt::Key_Return:
          qDebug() << "Return keyPress";
          break;
       case Qt::Key_Enter:
          qDebug() << "Enter(keypad) keyPress";
          break;
       case Qt::Key_Home:
          qDebug() << "Home keyPress";
          break;
       case Qt::Key_Left:
          qDebug() << "Left keyPress";
          break;
       case Qt::Key_Down:
          qDebug() << "Down keyPress";
          break;
       case Qt::Key_Space:
          qDebug() << "Space keyPress";
          break;
       case Qt::Key_F1:
          qDebug() << "F1 keyPress";
          break;
       case Qt::Key_0:
          qDebug() << "0(keypad) keyPress";
          break;
       default:
          qDebug("keyPress %x", pEvent->key());
          break;
    }
 }



複数のキーの取得

方法 1

1つのキーボードイベントで、複数のキーを取得する。

 // MainWindows.h
 
 class MainWindow : public QMainWindow
 {
 Q_OBJECT
 
 // ...略
 
 private:
    Ui::MainWindow *ui;
    bool m_bFirstRelease;
    QSet<Qt::Key> m_keysPressed;
 
 protected:
    keyPressEvent(QKeyEvent *pEvent)
    keyReleaseEvent(QKeyEvent *pEvent)
 
 // ...略
 
 };


 // MainWindow.cpp
 
 void MainWindow::keyPressEvent(QKeyEvent *pEvent)
 {
    m_bFirstRelease = true;
    m_keysPressed += pEvent->key();
 }
 
 void MainWindow::keyReleaseEvent(QKeyEvent *pEvent)
 {
    if(m_bFirstRelease)
    {
       processMultiKeys(keysPressed);
    }
 
    m_bFirstRelease = false;
 
    m_keysPressed -= pEvent->key();
 }


方法 2

押下したキーをQSetクラスに追加して、キーを離す時にQSetクラスから削除する。
イベントフィルタを使用して、主要なイベントを捕捉する。

 // MainWindow.h
 
 class MainWindow : public QMainWindow
 {
 Q_OBJECT
 
 // ...略
 
 private:
    Ui::MainWindow *ui;
    bool m_bFirstRelease;
    QSet<int> m_keysPressed;
 
 protected:
    bool eventFilter(QObject *obj, QEvent *pEvent);
    keyPressEvent(QKeyEvent *pEvent)
    keyReleaseEvent(QKeyEvent *pEvent)
 
 // ...略
 
 };


 // コンストラクタでイベントフィルタをインストールする
 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
 {
    installEventFilter(this);
 }
 
 bool MainWindow::eventFilter(QObject *obj, QEvent *pEvent)
 {
    if(pEvent->type() == QEvent::KeyPress)
    {
       m_keysPressed += ((QKeyEvent*)pEvent)->key();
 
       if(m_keysPressed.contains(Qt::Key_D) && m_keysPressed.contains(Qt::Key_W))
       {  // [D]キーと[W]キーを同時に押下する場合
          // ...処理を記述
       }
    }
    else if(pEvent->type() == QEvent::KeyRelease)
    {
       m_keysPressed -= ((QKeyEvent*)pEvent)->key();
    }
 
    return false;
 }


方法 3

イベントフィルタを使用して、キーボードやマウスのイベントを一括で処理する。
ただし、全てのイベントを処理できるか不明である。

イベント処理の順番は、以下のような流れである。

  1. フォーカスされているオブジェクトのイベント処理
  2. イベントフィルタ(eventFilterメソッド)
  3. mousePressEventメソッドやkeyPressEventメソッド等


KeyPress関連のイベント等は、イベントフィルタの前にオブジェクトで消費されるため、
オブジェクトで使用されなかったイベントのみをイベントフィルタで取得することができる。

 // MainWindow.h
 
 // イベントフィルタとイベントメソッドを宣言する
 protected:
    bool eventFilter(QObject *object, QEvent *event);
 
 private:
    bool eventKeyPress(QKeyEvent *event);
    bool eventKeyRelease(QKeyEvent *event);


 // MainWindow.cpp
 
 // コンストラクタでイベントフィルタをインストールする
 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
 {
    installEventFilter(this);
 }
 
 // イベントごとに必要な処理を行う
 // trueを返すとイベントは破棄される
 // installEventFilterメソッドのオブジェクト(QObject)が第1引数として渡されるが、
 // ここでは使用しないため、名前を指定しない
 bool MainWindow::eventFilter(QObject *, QEvent *event)
 {
    bool bRtn = false;
 
    if(event->type() == QEvent::KeyPress)
    {
       bRtn = eventKeyPress(static_cast<QKeyEvent *>(event));
    }
    else if(event->type() == QEvent::KeyRelease)
    {
       bRtn = eventKeyRelease(static_cast<QKeyEvent *>(event));
    }
 
    return bRtn;
 }
 
 // キー押下時の処理
 // 特定のキーを判定してデバッグ出力する
 // その他のキーはfalseを返してイベントを残す
 // キーを押下している間のリピートキーは破棄する
 // イベントが取得できるかどうかは、フォーカス次第となる
 bool MainWindow::eventKeyPress(QKeyEvent *event)
 {
    if(event->isAutoRepeat())
    {
       return true;
    }
 
    switch(event->key())
    {
       case Qt::Key_Escape:
          qDebug() << "Esc press";
          break;
       case Qt::Key_Return:
          qDebug() << "Return press";
          break;
       case Qt::Key_Enter:
          qDebug() << "Enter(keypad) press";
          break;
       case Qt::Key_Home:
          qDebug() << "Home press";
          break;
       case Qt::Key_Left:
          qDebug() << "Left press";
          break;
       case Qt::Key_Down:
          qDebug() << "Down press";
          break;
       case Qt::Key_Space:
          qDebug() << "Space press";
          break;
       case Qt::Key_F1:
          qDebug() << "F1 press";
          break;
       case Qt::Key_0:
          qDebug() << "0(keypad) press";
          break;
       default:
          qDebug("press %x", event->key());
          return false;
    }
 
    return true;
 }
 
 // キーを離した時の処理
 // KeyReleaseイベントではオブジェクトをあまり消費しないため、イベントを取得できる可能性が高い
 bool MainWindow::eventKeyRelease(QKeyEvent *event)
 {
    if(event->isAutoRepeat())
    {
       return true;
    }
 
    switch(event->key())
    {
       case Qt::Key_Tab:
          qDebug() << "Tab release";
          break;
       case Qt::Key_Backtab:
          qDebug() << "Backtab release";
          break;
       default:
          qDebug("release %x", event->key());
          return false;
    }
 
    return true;
 }