基本的には「QML Keys Element」を使用すれば可能です。
また基本的な動作は以前の記事の「QML(Qt)でキーイベントの拾い方」のとおりです。
ただ、気になる点があります。
/// 気になる点 ///
・ハードキーは拾えるものと拾えないものがある。
・戻るキーをブロックして任意の動作をさせれない。
(ユーザーに押下されると必ずアクティビティが閉じてしまう。)
・文字のハードキーとメニューなどの機能系のハードキーで動作が違うかも?
(エミュレータでしか確認できてないですが)
本当は、戻るキーのイベントを拾ってメニューを消すとかの処理をしてaccepted=trueってしてアクティビティを閉じるのを阻止したかったのです。
イベントが拾えたとしてもacceptedの指定で阻止できるか不明です。
Ministro2のソース見て確認しようと思ったらsource forgeに肝心なところがないんですよね。 GPLなので言えば見せてくれると思うのですが。
/// 動作検証結果 ///
・トップのRectangle(など)に「focus:true」とする。
→キーイベントは拾えない。
通常はこれでOKのはず。
・何かのタイミングで、「forceActiveFocus()」を実行する。
→キーイベントが拾えるようになる。
ただし、トップのRectanbleのonCompletedで実行しても効果なし。
別のタイミングで実行する必要がある。
・TextInputエレメントなどにフォーカスを当てる。
→TextInput側ではpress/releaseの両方にイベント起きるが
トップのRectangle側にはreleaseしかこない。
(この動作に関してはエミュレータでのみの確認です。)
・メニューなどのハードキーを押した場合(かつTextInputにフォーカス)
→TextInput/Rectangleのどちらにもpress/releaseの両方にイベントが起きる。
ただイベントが拾えるのは後述のキーコードが解っているものだけ。
補足
TextInputにフォーカスがある時の動作ですが、イベントの中で以下のように「KeyEvent.accepted」をtrueにすると親のRectangleへイベントは飛ばなくなります。
event.accepted = true;
/// ハードキーのコード ///
・ホーム : ?
・メニュー : 16777301
・戻る : ?
・検索 : 16777362
・カメラ : ?
・ボリュームダウン : 16777328
・ボリュームアップ : 16777330
・電源 : ?
・受話 : 17825796
・終話 : ?
?のキーは拾えませんでした。
また基本的な動作は以前の記事の「QML(Qt)でキーイベントの拾い方」のとおりです。
ただ、気になる点があります。
/// 気になる点 ///
・ハードキーは拾えるものと拾えないものがある。
・戻るキーをブロックして任意の動作をさせれない。
(ユーザーに押下されると必ずアクティビティが閉じてしまう。)
・文字のハードキーとメニューなどの機能系のハードキーで動作が違うかも?
(エミュレータでしか確認できてないですが)
本当は、戻るキーのイベントを拾ってメニューを消すとかの処理をしてaccepted=trueってしてアクティビティを閉じるのを阻止したかったのです。
イベントが拾えたとしてもacceptedの指定で阻止できるか不明です。
Ministro2のソース見て確認しようと思ったらsource forgeに肝心なところがないんですよね。 GPLなので言えば見せてくれると思うのですが。
/// 動作検証結果 ///
・トップのRectangle(など)に「focus:true」とする。
→キーイベントは拾えない。
通常はこれでOKのはず。
Aキーを押した時のログ
D/Qt (25598): keyDown
D/Qt (25598): keyUp
D/Qt (25598): keyDown
D/Qt (25598): keyUp
・何かのタイミングで、「forceActiveFocus()」を実行する。
→キーイベントが拾えるようになる。
ただし、トップのRectanbleのonCompletedで実行しても効果なし。
別のタイミングで実行する必要がある。
Aキーを押した時のログ
D/Qt (25598): keyDown
D/Qt (25598): rect down key=65
D/Qt (25598): keyUp
D/Qt (25598): rect up key=65
D/Qt (25598): keyDown
D/Qt (25598): rect down key=65
D/Qt (25598): keyUp
D/Qt (25598): rect up key=65
・TextInputエレメントなどにフォーカスを当てる。
→TextInput側ではpress/releaseの両方にイベント起きるが
トップのRectangle側にはreleaseしかこない。
(この動作に関してはエミュレータでのみの確認です。)
Aキーを押した時のログ
D/Qt (25598): keyDown
D/Qt (25598): input down key=65
D/Qt (25598): keyUp
D/Qt (25598): input up key=65
D/Qt (25598): rect up key=65
D/Qt (25598): keyDown
D/Qt (25598): input down key=65
D/Qt (25598): keyUp
D/Qt (25598): input up key=65
D/Qt (25598): rect up key=65
・メニューなどのハードキーを押した場合(かつTextInputにフォーカス)
→TextInput/Rectangleのどちらにもpress/releaseの両方にイベントが起きる。
ただイベントが拾えるのは後述のキーコードが解っているものだけ。
Menuキーを押した時のログ
D/Qt (27992): keyDown
D/Qt (27992): input down key=16777301
D/Qt (27992): rect down key=16777301
D/Qt (27992): keyUp
D/Qt (27992): input up key=16777301
D/Qt (27992): rect up key=16777301
D/Qt (27992): keyDown
D/Qt (27992): input down key=16777301
D/Qt (27992): rect down key=16777301
D/Qt (27992): keyUp
D/Qt (27992): input up key=16777301
D/Qt (27992): rect up key=16777301
補足
TextInputにフォーカスがある時の動作ですが、イベントの中で以下のように「KeyEvent.accepted」をtrueにすると親のRectangleへイベントは飛ばなくなります。
event.accepted = true;
/// ハードキーのコード ///
・ホーム : ?
・メニュー : 16777301
・戻る : ?
・検索 : 16777362
・カメラ : ?
・ボリュームダウン : 16777328
・ボリュームアップ : 16777330
・電源 : ?
・受話 : 17825796
・終話 : ?
?のキーは拾えませんでした。
検証コード
<Category : Qt>
import QtQuick 1.0 //import "./Database.js" as DB Rectangle { id: _root width: 360 height: 360 focus: true Text { id: _text text: qsTr("code1=") anchors.centerIn: parent } Text { id: _text2 text: qsTr("code2=") anchors.top: _text.bottom anchors.topMargin: 10 anchors.horizontalCenter: parent.horizontalCenter } MouseArea { anchors.fill: parent onClicked: { // これは効果あり _root.forceActiveFocus(); } } TextInput{ id: _input anchors.top: _text2.bottom anchors.topMargin: 10 anchors.horizontalCenter: parent.horizontalCenter width: 200 height: 50 text: "default" // TextInputのキーイベント Keys.onPressed: { console.debug("input down key=" + event.key + ",accept=" + event.accepted); // event.accepted = true; //これを実行するとrectへイベントはいかない } Keys.onReleased: { console.debug("input up key=" + event.key + ",accept=" + event.accepted); _text2.text = "code2=" + event.key; // event.accepted = true; //これを実行するとrectへイベントはいかない } } // ルートのRectangleのキーイベント Keys.onPressed: { console.debug("rect down key=" + event.key + ",accept=" + event.accepted); } Keys.onReleased: { console.debug("rect up key=" + event.key + ",accept=" + event.accepted); _text.text = "code1=" + event.key; } // 読み込み完了時 Component.onCompleted: { // これは効果無し _root.forceActiveFocus(); } }