「Qtのコントロール - キーボード」の版間の差分
ナビゲーションに移動
検索に移動
60行目: | 60行目: | ||
== 複数のキーの取得 == | == 複数のキーの取得 == | ||
==== 方法 1 ==== | |||
1つのキーボードイベントで、複数のキーを取得する。<br> | 1つのキーボードイベントで、複数のキーを取得する。<br> | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// MainWindows.h | |||
void | 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) | |||
// ...略 | |||
}; | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// MainWindow.cpp | |||
void MainWindow::keyPressEvent(QKeyEvent *pEvent) | |||
{ | { | ||
m_bFirstRelease = true; | m_bFirstRelease = true; | ||
m_keysPressed += pEvent->key(); | |||
} | } | ||
void | void MainWindow::keyReleaseEvent(QKeyEvent *pEvent) | ||
{ | { | ||
if(m_bFirstRelease) | if(m_bFirstRelease) | ||
79行目: | 103行目: | ||
m_bFirstRelease = false; | m_bFirstRelease = false; | ||
m_keysPressed -= pEvent->key(); | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
==== 方法 2 ==== | |||
イベントフィルタを使用して、キーボードやマウスのイベントを一括で処理する。<br> | |||
ただし、全てのイベントを処理できるか不明である。<br> | |||
<br> | |||
イベント処理の順番は、以下のような流れである。<br> | |||
# フォーカスされているオブジェクトのイベント処理 | |||
# イベントフィルタ(<code>eventFilter</code>メソッド) | |||
# <code>mousePressEvent</code>メソッドや<code>keyPressEvent</code>メソッド等 | |||
<br> | |||
KeyPress関連のイベント等は、イベントフィルタの前にオブジェクトで消費されるため、<br> | |||
オブジェクトで使用されなかったイベントのみをイベントフィルタで取得することができる。<br> | |||
<syntaxhighlight lang="c++"> | |||
// MainWindow.h | |||
// イベントフィルタとイベントメソッドを宣言する | |||
protected: | |||
bool eventFilter(QObject *object, QEvent *event); | |||
private: | |||
bool eventKeyPress(QKeyEvent *event); | |||
bool eventKeyRelease(QKeyEvent *event); | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// 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; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
2021年3月30日 (火) 10:33時点における版
概要
キーボード入力
フォーカスを持つオブジェクトに破棄されたイベントは、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
イベントフィルタを使用して、キーボードやマウスのイベントを一括で処理する。
ただし、全てのイベントを処理できるか不明である。
イベント処理の順番は、以下のような流れである。
- フォーカスされているオブジェクトのイベント処理
- イベントフィルタ(
eventFilter
メソッド) 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;
}