右クリックした時に表示されるアレです。
僕が知らないだけじゃなければQMLでそお言うものを表示する機能はありませんので自前で作る必要があります。
なので以前紹介した「QML(Qt)でListViewのサイズに合わせて何かのサイズを調節する」を利用して作ってみました。
あと、コンテキストメニューにありがちな区切り線も表示できるようにしています。
追記
なのですが、実際にはListViewを使わずにColumnとRepeaterを使って実装しました。
高さの調節が要らなくなった分すっきりしています。
ですがModelとDelegateは再利用できているのでなんだかいい感じ?かもです。
今回もありがたいご指摘がm(。。)m
ただしコレにも弱点があってデスクトップ向けでキーボード操作に対応したい場合はListViewのHightlight機能を使わないとしんどいので臨機応変にってかんじですね。
/// ポイント1 ///
今回のポイントは本来表示するコンテンツとコンテキストメニューを別のレイヤー(的なもの)に分けて管理するってことです。
必要な時だけメニューのレイヤを表示します。
こんなイメージです。
水色のレイヤーを表示非表示をコントロールすることで肝心のメニューをコンテンツの上へ重ねて表示します。
また、余ったエリアをクリックした時に下のコンテンツへマウスのイベントが飛ばないようにするために水色レイヤーは見えないようにしつつ全体を覆います。
またそのエリアをクリックしたらメニューを消します。
/// ポイント2 ///
メニューに区切りを入れるようにしています。
モデルに含まれるテキストが「-」ハイフンだった場合に区切りになるようにしています。
で、区切りの時は高さが違うので前回の記事が生きてきたりします。
デリゲートの高さ自体を表示するテキストの高さから計算していますので区切りの場合はフォントサイズを変えて調節してます。
/// サンプルコードを実行したスクリーンショット ///
画像:@keikawagutiさん
実際にはメニューを複数使ったりするので今回の方法ではちょっと乱暴すぎるので工夫がいると思います。
/// サンプルコード ///
今回はModelとDelgateは別ファイルにしました。
<Category : Qt>
僕が知らないだけじゃなければQMLでそお言うものを表示する機能はありませんので自前で作る必要があります。
なので以前紹介した「QML(Qt)でListViewのサイズに合わせて何かのサイズを調節する」を利用して作ってみました。
あと、コンテキストメニューにありがちな区切り線も表示できるようにしています。
追記
なのですが、実際にはListViewを使わずにColumnとRepeaterを使って実装しました。
高さの調節が要らなくなった分すっきりしています。
ですがModelとDelegateは再利用できているのでなんだかいい感じ?かもです。
今回もありがたいご指摘がm(。。)m
ただしコレにも弱点があってデスクトップ向けでキーボード操作に対応したい場合はListViewのHightlight機能を使わないとしんどいので臨機応変にってかんじですね。
/// ポイント1 ///
今回のポイントは本来表示するコンテンツとコンテキストメニューを別のレイヤー(的なもの)に分けて管理するってことです。
必要な時だけメニューのレイヤを表示します。
こんなイメージです。
水色のレイヤーを表示非表示をコントロールすることで肝心のメニューをコンテンツの上へ重ねて表示します。
また、余ったエリアをクリックした時に下のコンテンツへマウスのイベントが飛ばないようにするために水色レイヤーは見えないようにしつつ全体を覆います。
またそのエリアをクリックしたらメニューを消します。
/// ポイント2 ///
メニューに区切りを入れるようにしています。
モデルに含まれるテキストが「-」ハイフンだった場合に区切りになるようにしています。
で、区切りの時は高さが違うので前回の記事が生きてきたりします。
デリゲートの高さ自体を表示するテキストの高さから計算していますので区切りの場合はフォントサイズを変えて調節してます。
/// サンプルコードを実行したスクリーンショット ///
画像:@keikawagutiさん
実際にはメニューを複数使ったりするので今回の方法ではちょっと乱暴すぎるので工夫がいると思います。
/// サンプルコード ///
今回はModelとDelgateは別ファイルにしました。
import QtQuick 1.0 Rectangle { id: _root width: 360 height: 360 // コンテンツのレイヤー MouseArea { id: _contentLayer anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: { if(pressedButtons === Qt.LeftButton){ // 左クリックは終了 Qt.quit(); }else{ // 右クリックはコンテキスト表示 _root.state = "ContextOn"; _menu.x = mouse.x; _menu.y = mouse.y; } } // コンテンツ Image { id: _image anchors.fill: parent source: "./wallpaper.jpg" fillMode: Image.PreserveAspectCrop clip: true smooth: true } } // コンテキストメニューを表示するレイヤー MouseArea { id: _menuLayer anchors.fill: parent opacity: 0 acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: { // 空白をクリックしたら閉じる _root.state = ""; } Column { id: _menu Repeater { model: ContextModel{ } delegate: ContextDelegate { // 表示する値を設定 itemIndex: _index itemTitle: _title } } } } states: [ State { name: "ContextOn" PropertyChanges { target: _menuLayer opacity: 1.0 } } ] }
// ContextModel.qml import QtQuick 1.0 ListModel { ListElement { _index: 2 _title: "About" } ListElement { _index: -1 _title: "-" } ListElement { _index: 1 _title: "Exit" } }
// ContextDelegate.qml import QtQuick 1.0 Rectangle { id: _root width: 200 height: _title.font.pixelSize * 2.5 color: "#000000" border.color: "#00000000" property int itemIndex: -1 property alias itemTitle: _title.text Text { id: _title color: "#dddddd" anchors.centerIn: parent font.pointSize: 12 wrapMode: "WordWrap" onTextChanged: { if(text === "-"){ // 区切り線の時は高さを低くする font.pixelSize = 2; _title.visible = false; _line.visible = true; }else{ // 通常の時 font.pointSize = 12; _title.visible = true; _line.visible = false; } } } // 区切り線 Rectangle{ id: _line anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 5 anchors.rightMargin: 5 anchors.verticalCenter: parent.verticalCenter color: "#aaaaaa" height: 1 visible: false } MouseArea { id: _mouseArea anchors.fill: parent hoverEnabled: true //クリック onClicked: { if(_title.text === "-"){ }else{ // クリックしたよ } } } }