Domanda

I have, for example, such model in my 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!")
    }
}

So, I have ListView element with id: optionlist, and ListDelegate for control list elements. I have several model - all this elements created for menu options in project. So, code onModelChanged: optionlist.model.onStart() in list file work perfectly.

Problem is to call actionClick() function from listDelegate script OnClicked in MouseArea element. Is it possible to do this? Something like this: optionlist.model.ContentItem.children[currentIndex].actionClick() maybe or something else?

UPDATE: Sorry, Amit Tomer, maybe I don't explain task correctly... So, I need element in model with next fields:

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.

All this must be done for clearly and easily filled up All option menu tree. This menu tree will be write in separate file.

In code below I show worked model:

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
    }
}

As you see, I wrote something like You say. It's okay, If I don't find better solution. Beter solution - remove actionClick() general function and added it's part (code in case blocks) to ListElement respectively. And call it when Element's click.

I don't know how call this function from ListElement. In WPF I would just create custom component, which replease ListElement and just all! But I don't know how do this in QML.

I anything not clear - please ask.

UPDATE: Problem solved. My variant in answers. Thanks to all.

È stato utile?

Soluzione 2

Problem solved. But not quite as planning at first.

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)
    }
}

As you see, changing optionMenu solved by cleaning model and filling by elements from Item.

Each Item - is one screen.

Service Items - general component and functions.

Now I think, it would be beter to separate menuTree (Item components) in other file, because there will be 3 different OptionMenu with different Trees.

Altri suggerimenti

How about this:

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}
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top