僕が知らないだけじゃなければ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{
// クリックしたよ
}
}
}
}
コメント