上一篇博文我们说到了qml组件下拉列表的实现,但只能支持单选功能。在这篇文章,我将会讲一下本人下拉列表复选功能的实现方法(不代表是好方法,仅供参考)。
首先,在点击和鼠标划过等高亮效果方面,依然是自定义的;每个item被选中将会有高亮。然后和单选下拉列表不一样,点击选中时并没有立即收回。
同时,定义了一个数组,数组元素的值为0和1(其意义如代码中注释所示);在触发Click事件时,将会改变这些元素的值。在外部获取选中的item时,直接从这个数组的元素的值可获知。这肯定不是很好的方法,但是绝对简单了。
qml代码如下:
// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
import QtQuick 1.1
Rectangle {
id:comboBox
property variant daysOfWeekFlag:[0,0,0,0,0,0,0] // 1代表当日选中,0代表当日未选中
property variant items: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
signal comboClicked;
width: 110;
height: 30;
smooth:true;
onDaysOfWeekFlagChanged: {
chosenItemText.text = "";
for(var i=0; i<daysOfWeekFlag.length; ++i)
{
if(daysOfWeekFlag[i] !== 0)
{
chosenItemText.text += items[i];
chosenItemText.text += " ";
}
}
if(chosenItemText.text == "")
chosenItemText.text = "点击可选择"
}
Rectangle {
id:chosenItem
radius:4;
width:chosenItemText.width > parent.width?chosenItemText.width:parent.width
height:comboBox.height;
color: "#2EB3FF"
smooth:true;
Text {
id:chosenItemText
anchors.top: parent.top;
anchors.left: parent.left;
anchors.margins: 3;
anchors.verticalCenter: parent.verticalCenter
text:"点击可选择"
font.family: "Arial"
font.pointSize: 14;
smooth:true
}
MouseArea {
anchors.fill: parent;
onClicked: {
comboBox.state = comboBox.state==="dropDown"?"":"dropDown"
}
}
}
Rectangle {
id:dropDown
width:comboBox.width;
height:0
clip:true;
radius:4;
anchors.top: chosenItem.bottom;
anchors.topMargin: 2
color: "lightgray"
Rectangle{
id: dropDownMask
height: 3
width:parent.width
anchors.bottom: listView.top
}
ListView {
id:listView
height:154
width: dropDown.width-4
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: dropDownMask.bottom
anchors.topMargin: -1
z:1
model: comboBox.items
currentIndex: 0
delegate: Item{
width:listView.width;
height: comboBox.height;
Rectangle {
id: highLight
width:listView.width;
height:comboBox.height;
color: "green";
opacity: daysOfWeekFlag[index] === 1? 1:0;
radius: 4
z:0
}
Text {
text: modelData
anchors.top: parent.top;
anchors.left: parent.left;
anchors.margins: 5;
font.pointSize: 14;
z:1
}
MouseArea {
anchors.fill: parent;
hoverEnabled: true
onClicked: {
var isSelected = (daysOfWeekFlag[index]+1)%2;
var daysOfWeekCopy = daysOfWeekFlag;
if(isSelected)
{
highLight.opacity = 1;
daysOfWeekCopy[index] = 1;
}
else
{
highLight.opacity = 0.5;
daysOfWeekCopy[index] = 0;
}
comboBox.comboClicked();
daysOfWeekFlag = daysOfWeekCopy;
}
onEntered: {
if(daysOfWeekFlag[index] === 0)
highLight.opacity = 0.5;
}
onExited:{
if(daysOfWeekFlag[index] === 0)
highLight.opacity = 0;
}
}
}
}
MouseArea{
anchors.fill: dropDown
hoverEnabled: true
onExited: {
if(!containsMouse)
comboBox.state = "";
}
}
}
states: State {
name: "dropDown";
PropertyChanges { target: dropDown; height:listView.height+4;}
}
transitions: Transition {
NumberAnimation { target: dropDown; properties: "height"; easing.type: Easing.OutExpo; duration: 300 }
}
}
备注
貌似直接对在qml中定义的数组操作无效,但是这样就可以绕过这个问题了。至于是什么原因,还没有找到;所以,欢迎大家指点。
var daysOfWeekCopy = daysOfWeekFlag;
daysOfWeekCopy[index] = 1;
daysOfWeekFlag = daysOfWeekCopy;