前回の「QML(Qt)でチェックボックスを作る」を使って作ります。
ついでにグループボックスも作りました。
/// 今回のポイント ///
・初期表示時の選択アイテムを選べるようにした
・Repeaterを使ってListModelで内容を定義するだけでCheckBoxの配置を簡単にできるようにした
・childrenはRepeaterには定義されないのでColumnのを使用する
・Columnのchildere配列にRepeaterも含まれるので注意
・ListModelのパラメータに「_key」を追加して項目を一意に表現できるようにした
Repeaterのchilderenにはオブジェクトは配置されずにColumnに配置されてました。
その際、Repeater自身もColumnのchildrenに含まれるので注意です。
場所的にはリストの最後に居たので子供の数を「-1」しておけば扱い的にはなんとかなります。
ListModelのListElementのパラメータに「_key」を追加して一意に設定しておくと項目の数を増やしたり順番を入れ替えたりした時のデグレを防げますし可読性があがります。
上位のプログラムで選択された項目を振り分ける時のswitch文とかが楽ですよね。
#define的な物がなくて定数化がやりにくいので結構大事かなと思います。
(実はあるのかな?誰かいい方法教えてください)
各チェックボックスはColumnを使用して配置しているのでGridやRowを使えば並べ方もバリエーション作れます。
使用するときはonKeyChangedイベントで項目の選択変更を拾うのが良いと思います。
インデックスもキーもどちらも変更されて新しい状態になっています。
すぐわかりますがグループボックスはちょっと弱点があります。
文字の背景を透過させれません。
/// スクリーンショット ///
サンプルコードを実行した時のものです。
/// サンプルコード ///
まず呼び出し側のサンプル
// main.qml import QtQuick 1.0 import "Components" Rectangle { width: 360 height: 360 Column{ anchors.fill: parent anchors.margins: 5 spacing: 5 // グループボックス GroupBox{ text: "Radio box test" radius: 5 height: _radio.height + textHeight * 1.5 // ラジオボックス RadioBox{ id: _radio currentIndex: 1 // 選択の初期位置変更 anchors.top: parent.top anchors.margins: parent.textHeight * 1.2 anchors.left: parent.left anchors.leftMargin: 5 // 項目の設定 model: RadioBoxModel{ } // 項目が変更された時のイベント // こっちが先に呼ばれる(まだキーは変更されてない) onCurrentIndexChanged: { console.debug("onCurrentIndexChanged::" + "index=" + currentIndex + ", text=" + items[currentIndex].text + ", text=" + getCurrentItemText() + ", count=" + getItemCount() + ", key=" + currentKey); } // 項目が変更されてキーが変更された時のイベント // こっちが後に呼ばれる onCurrentKeyChanged: { console.debug("onKeyChanged::" + "index=" + currentIndex + ", text=" + items[currentIndex].text + ", text=" + getCurrentItemText() + ", count=" + getItemCount() + ", key=" + currentKey); } } } } }
ラジオボックスの内容を定義するモデル
// RadioBoxModel.qml import QtQuick 1.0 ListModel { ListElement { _key: 0 _text: "CheckBox0" } ListElement { _key: 1 _text: "CheckBox1" } ListElement { _key: 2 _text: "CheckBox2" } ListElement { _key: 3 _text: "CheckBox3" } }
ラジオボックス本体のコード
// RadioBox.qml import QtQuick 1.0 Item { id: _root width: _items.width height: _items.height property int currentKey: 0 // 現在のアイテムのmodelで指定されたキー(読込み専用) property int currentIndex: 0 // 現在の選択アイテムのインデックス property alias items: _items.children // checkboxのリスト property alias itemSpacing: _items.spacing // アイテム同士の間隔 property alias model: _itemsRepeater.model // 読込み完了時の処理 Component.onCompleted: { // 初期位置を設定する if(currentIndex < 0 || currentIndex >= getItemCount()){ currentIndex = 0; } _items.children[currentIndex].checked = true; currentKey = _itemsRepeater.model.get(currentIndex)._key; } // 含まれるcheckboxの数 function getItemCount(){ // Repeaterの分を引く return _items.children.length - 1; } // 現在選択されているアイテムのテキスト function getCurrentItemText(){ return _items.children[currentIndex].text; } // 自分以外のチェックを外す function itemClicked(index){ for(var i=0; i< getItemCount(); i++){ if(i == index){ // 自分自身はなにもしない }else{ // 自分以外のチェックを外す _items.children[i].checked = false; } } } // 実際の内容 Column{ id: _items spacing: 5 // リピータでお手軽配置 // modelは外から指定する // _key は一意にすること // _text は表示したい文字列 Repeater { id: _itemsRepeater delegate: CheckBox{ id: _item text: _text property int key: _key onClicked: { //インデックスなどを更新する currentIndex = index; currentKey = key; // 自分以外のチェックを外す itemClicked(index); } } } } }天の声があったので少し修正。
itemClickedの引数をindexだけに変更。
delgateの中では「index」が使えるそうです。
おまけ的なグループボックス
// GroupBox.qml import QtQuick 1.0 Item { width: parent.width height: parent.height property alias text: _text.text // 表示するメッセージ property alias color: _text.color // 色 property alias fontPointSize: _text.font.pointSize // フォントサイズ property alias textHeight: _text.height // テキストの高さ property alias textBkColor: _textArea.color // テキストの背景色 property alias radius: _border.radius // 角 property color borderColor: "#999999" // 枠の色 property int borderWidth: 1 // 枠の太さ // 枠線 Rectangle { id: _border x: 0 y: _text.height / 2 width: parent.width height: parent.height - y border.color: borderColor border.width: borderWidth } // タイトル Rectangle { id: _textArea width: _text.width height: _text.height anchors.top: parent.top anchors.left: parent.left anchors.leftMargin: 5 color: "#ffffff" Text{ id: _text text: "Title" } } }
コメント