例如,我在QML中有这样的模型:
ListModel{
id: mainlist
ListElement
{
name: "Name1"
type: "subMenu"
toogle: false
iconSource: ""
function actionClick()
{
console.log("actionclick is passed for 0 item!")
}
}
ListElement
{
name: "Manage Favorites"
type: "subMenu"
toogle: false
iconSource: "image://provider/common/endless_menu/list_icons/fav"
function actionClick()
{
console.log("actionclick is passed for 1 item!")
}
}
ListElement
{
name: "Name2"
type: "subMenu"
toogle: false
iconSource: "image://provider/common/endless_menu/list_icons/active"
function actionClick()
{
console.log("actionclick is passed for 2 item!")
}
}
ListElement
{
name: "Name3"
type: "subMenu"
toogle: false
iconSource: "image://provider/common/endless_menu/list_icons/scan"
function actionClick()
{
console.log("actionclick is passed for 3 item!")
}
}
ListElement
{
name: "Manual Frequency Input"
type: "commonBtn"
toogle: false
iconSource: ""
function actionClick()
{
console.log("actionclick is passed for 4 item!")
}
}
function onStart(currIndex)
{
console.log("test is passed for " + currIndex + "item!")
}
}
因此,我有一个带有id: optionlist
的ListView元素和一个用于控制列表元素的ListDelegate。
我有几个模型 - 为项目中的菜单选项创建的所有元素。
因此,列表文件中的代码onModelChanged: optionlist.model.onStart()
可以正常工作。
问题是从MouseArea元素中的listDelegate脚本actionClick()
调用OnClicked
函数。是否有可能做到这一点?
这样的事情:optionlist.model.ContentItem.children[currentIndex].actionClick()
可能还是别的什么?
更新: 对不起,Amit Tomer,也许我没有正确解释任务......所以,我需要模型中的元素和下一个字段:
name: - text for element
type: - type of element (button, radio button, check button or submenu) - needed for corect action when user clicked on this item
toogle: - boolean value for radio/check buttons state, and for some internal operations.
iconSource: - path for icon, if it needed.
function actionClick() - function, which will be execute when user clicked on this item.
所有这一切都必须完成,以便清楚,轻松地填满所有选项菜单树。此菜单树将写入单独的文件中。
在下面的代码中,我展示了工作模式:
Item{
id: menuoptions
property ListModel prev: manageFavorites
property bool root: true
//Main Menu
property alias mainlist: mainlist
ListModel{
id: mainlist
ListElement
{
name: "Band: "
type: "subMenu"
toggle: false
iconSource: ""
}
ListElement
{
name: "Manage Favorites"
type: "subMenu"
toggle: false
iconSource: "image://provider/common/endless_menu/list_icons/fav"
}
ListElement
{
name: "Show: "
type: "subMenu"
toggle: false
iconSource: "image://provider/common/endless_menu/list_icons/active"
}
ListElement
{
name: "Scan"
type: "subMenu"
toggle: false
iconSource: "image://provider/common/endless_menu/list_icons/scan"
}
ListElement
{
name: "Manual Frequency Input"
type: "commonBtn"
toggle: false
iconSource: ""
}
function actionClick(currIndex)
{
switch(currIndex)
{
case 0:
{
prev = mainlist
menuList.model = bandlist
break
}
case 1:
{
prev = mainlist
menuList.model = manageFavorites
break
}
case 2:
{
prev = mainlist
menuList.model = showlist
break
}
case 3:
{
console.log("Scan started")
mainlist.setProperty(3, "name", getScan())
break
}
case 4:
{
console.log("Speller for Manual Frequency Input open!")
break
}
}
}
function onStart()
{
console.log("root model loaded")
root = true
mainlist.setProperty(0, "name", "Band: " + getBand())
mainlist.setProperty(2, "name", "Show: " + getShow())
mainlist.setProperty(3, "name", getScan())
}
}
//First Lvl subMenu
property alias bandlist: bandlist
ListModel{
id: bandlist
... Analog menulist
}
property alias manageFavorites: manageFavorites
ListModel{
id: manageFavorites
... Analog menulist
}
property alias showlist: showlist
ListModel{
id: showlist
... Analog menulist
}
}
如你所见,我写了类似你说的话。没关系,如果我找不到更好的解决方案。 Beter解决方案 - 删除actionClick()常规函数,并将它的部分(case块中的代码)分别添加到ListElement。在点击元素时调用它。
我不知道如何从ListElement调用此函数。在WPF中,我只想创建自定义组件,它可以为ListElement提供所有内容!但我不知道在QML中这是怎么做的。
我还不清楚 - 请问。
更新:问题解决了。我在答案中的变体。谢谢大家。
答案 0 :(得分:0)
这个怎么样:
import QtQuick 1.0
Rectangle
{
color: "grey"
width: 800
height: 800
function actionClick(index)
{
if( 0 == listModel.get(index).internalIndex )
functionForElement1()
else if( 1 == listModel.get(index).internalIndex )
functionForElement2()
else if( 2 == listModel.get(index).internalIndex )
functionForElement3()
else if( 3 == listModel.get(index).internalIndex )
functionForElement4()
else if( 4 == listModel.get(index).internalIndex )
functionForElement5()
}
functionForElement1() { console.log("Inside Function 1") }
functionForElement2() { console.log("Inside Function 2") }
functionForElement3() { console.log("Inside Function 3") }
functionForElement4() { console.log("Inside Function 4") }
functionForElement5() { console.log("Inside Function 5") }
ListView
{
anchors.centerIn: parent
width: parent.width
height: parent.height
model: listModel
spacing: 10
delegate: Component
{
Rectangle
{
x: 350
y: 350
width: 100
height: 50
Text { text: name ; anchors.centerIn: parent }
MouseArea
{
anchors.fill: parent
onClicked: actionClick( index )
}
}
}
ListModel
{
id: listModel
ListElement { name: "Apple", internalIndex: 1}
ListElement { name: "badApple" , internalIndex: 2}
ListElement { name: "goodApple" , internalIndex: 3}
ListElement { name: "worseApple" , internalIndex: 4}
ListElement { name: "spoilledApple" , internalIndex: 5}
}
}
}
答案 1 :(得分:0)
问题解决了。但最初并不像计划那样。
import QtQuick 2.0
/*
Elements of model:
name - displayed text
type - type of element, for clicked event
toggle - state for radio and check btn
iconSource - path to icon
*/
/*
TYPE:
radioBtn
checkBtn
commonBtn
subMenu
*/
Item{
id: menuoptions
//property ListModel prev: listmodel
property Item curr: mainList
//TEST FUNCTIONS
property string band: "AM"
property string show: "All"
//END TEST FUNCTION
//Main Menu Radio
Item{
id: mainList
property int count: 7
property Item prev
children:
[
Item
{
property string name: "Band: "
property string type: "subMenu"
property bool toggle: false
property string iconSource: ""
property bool need: true
function onClick()
{
curr = bandList
loadModel()
}
},
Item
{
property string name: "Manage Favorites"
property string type: "subMenu"
property bool toggle: false
property string iconSource: "image://provider/common/endless_menu/list_icons/fav"
property bool need: true
function onClick()
{
curr = manageFavList
loadModel()
}
},
Item
{
property string name: "Show: "
property string type: "subMenu"
property bool toggle: false
property string iconSource: "image://provider/common/endless_menu/list_icons/active"
property bool need: true
function onClick()
{
curr = showList
loadModel()
}
},
Item
{
property string name: "Scan"
property string type: "subMenu"
property bool toggle: false
property string iconSource: "image://provider/common/endless_menu/list_icons/scan"
property bool need: true
function onClick()
{
if (!listmodel.get(menuList.currentIndex).toggle)
{
listmodel.setProperty(menuList.currentIndex, "toggle", true)
listmodel.setProperty(menuList.currentIndex, "name", "Scan")
}
else
{
listmodel.setProperty(menuList.currentIndex, "toggle", false)
listmodel.setProperty(menuList.currentIndex, "name", "Stop")
}
}
},
//optional
Item
{
property string name: "Alternative Frequency"
property string type: "checkBtn"
property bool toggle: false
property string iconSource: ""
property bool need: false
function onClick()
{
if (listmodel.get(menuList.currentIndex).toggle)
{
listmodel.setProperty(menuList.currentIndex, "toggle", false)
listmodel.setProperty(menuList.currentIndex + 1, "toggle", false)
}
else
{
listmodel.setProperty(menuList.currentIndex, "toggle", true)
}
}
},
Item
{
property string name: "Regionalization"
property string type: "checkBtn"
property bool toggle: false
property string iconSource: "image://provider/common/endless_menu/list_icons/scan"
property bool need: false
function onClick()
{
if (listmodel.get(menuList.currentIndex - 1).toggle)
{
if (listmodel.get(menuList.currentIndex).toggle)
{
listmodel.setProperty(menuList.currentIndex, "toggle", false)
}
else
{
listmodel.setProperty(menuList.currentIndex, "toggle", true)
}
}
}
},
//end optional
Item
{
property string name: "Manual Frequency Input"
property string type: "commonBtn"
property bool toggle: false
property string iconSource: ""
property bool need: true
function onClick()
{
console.log("Speller for Manual Frequency Input open!")
}
}
]
function preLoad()
{
console.log("preload Func")
children[0].name = "Band: " + band
children[2].name = "Show: " + show
if (band == "SAT" || band == "AM")
{
children[4].need = false
children[5].need = false
}
if (band == "FM")
{
children[4].need = true
children[5].need = true
}
}
}
//First Lvl subMenu Radio
Item{
id: bandList
property int count: 3
property Item prev: mainList
//Analog as mainList
}
Item{
id: manageFavList
property int count: 3
property Item prev: mainList
//Analog as mainList
function preLoad()
{
console.log("preload Func for Manage Favorite List")
//Insert into model fav stations from 0 item
//favcount = gateway.getFavCount()
}
function favClick()
{
console.log("Favorite item clicked")
}
}
Item{
id: showList
property int count: 2
property Item prev: mainList
//Analog as mainList
}
//Service Items
property alias listmodel: listmodel
ListModel{
id: listmodel
}
function loadModel()
{
console.log("loader menu")
favcount = 0;
listmodel.clear()
curr.preLoad()
for (var i=0;i<curr.count;i++)
{
if (curr.children[i].need){
listmodel.append({"name": curr.children[i].name,
"type":curr.children[i].type,
"toggle":curr.children[i].toggle,
"iconSource":curr.children[i].iconSource})
}
}
}
function actionClick(currIndex)
{
if (favcount == 0)
curr.children[currIndex].onClick()
else
{
if (currIndex <= favcount - 1)
curr.favClick()
else
curr.children[currIndex-favcount].onClick()
}
}
function toggled(index)
{
for (var i=0; i<listmodel.count; i++)
listmodel.setProperty(i, "toggle", false)
listmodel.setProperty(index, "toggle", true)
}
}
如您所见,通过清理模型和填充Item中的元素来解决更改optionMenu。
每个项目 - 是一个屏幕。
服务项目 - 一般组件和功能。
现在我想,在其他文件中分离menuTree(Item组件)会更好,因为将有3个不同的OptionMenu与不同的树。