0

I need to fill the QML menu with MenuItems from the model

I found that I can do it like this:

Menu {
    id: contextMenu

    Instantiator {
       model: menuItems
       MenuItem {
          text: model.text
       }

       // The trick is on those two lines
       onObjectAdded: contextMenu.insertItem(index, object)
       onObjectRemoved: contextMenu.removeItem(object)
   }
}

What is described in this answer:

QML - Filling menu with model items

It partially work now, but I get an error:

Parameter "object" is not declared

And I don't understand which object I should pass to the function contextMenu.insertItem(index, object)

2 Answers2

0

You need to pass in the parameters from the signal. Have a read Signal parameters.

ListModel {
    id: menuItems
    ListElement { text:"hello1" }
    ListElement { text:"hello2" }
    ListElement { text:"hello3" }
}

Menu {
    id: contextMenu
    visible: true

    Instantiator {
       model: menuItems

       MenuItem {
          text: model.text
       }

       onObjectAdded: function(index, object) {
           contextMenu.insertItem(index, object)
       }
       onObjectRemoved: function(index, object) {
           contextMenu.removeItem(object)
       }
   }
}
iam_peter
  • 3,205
  • 1
  • 19
  • 31
  • 1
    Note that this is new syntax in Qt6 that wasn't required in Qt5. That's most likely why older suggestions don't work anymore. – JarMan Feb 09 '23 at 16:19
  • 1
    I'm not sure why the example isn't showing up on https://doc.qt.io/qt-6/qml-qtquick-controls2-menu.html, but there's been an example demonstrating how to use Instantiator for a while now: https://doc-snapshots.qt.io/qt6-dev/qml-qtquick-controls2-menu.html#dynamically-generating-menu-items – Mitch Feb 10 '23 at 07:26
0

In this case, because MenuItem is a subclass of Item, you can use Repeater instead of Instantiator:

import QtQuick
import QtQuick.Controls
Page {
    ListModel {
        id: menuItems
        ListElement { text:"hello1" }
        ListElement { text:"hello2" }
        ListElement { text:"hello3" }
    }
    Button {
        id: btn
        anchors.horizontalCenter: parent.horizontalCenter
        y: 100
        text: qsTr("Show Menu")
        onClicked: contextMenu.open()
    }
    Menu {
        id: contextMenu
        x: btn.x
        y: btn.y + btn.height
        Repeater {
            model: menuItems
            MenuItem {
                text: model.text
            }
        }
    }
}

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75