Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Cant make Instantiator work with QList<QObject*>

Cant make Instantiator work with QList<QObject*>

Scheduled Pinned Locked Moved QML and Qt Quick
11 Posts 3 Posters 4.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    shukurmukur
    wrote on last edited by
    #1

    I am developing for Android and trying to create a Menu with items populated dynamically from a model which is assigned from C++.

    QML I use is like this:
    @
    ApplicationWindow {
    menuBar: MenuBar {
    Menu {
    id: menu
    Instantiator {
    id: menuInstantiator
    MenuItem {
    text: model.title || ""
    }
    onObjectAdded: menu.insertItem(index, object)
    onObjectRemoved: menu.removeItem(object)
    }
    }
    }
    }
    @

    C++ code is like this:
    @
    class Info: public QObject
    {
    Q_OBJECT

    // Properties for use in QML
    Q_PROPERTY(QString id READ id)
    Q_PROPERTY(QString title READ title)
    

    public:
    Info(const QString& id, QObject *parent = 0);

    QString id() const { return m_id; }
    QString title() const { return m_title; }
    

    private:
    QString m_id;
    QString m_title;
    };

    ...
    QList<QObject*> infos;
    infos.append(new Info(1));
    infos.append(new Info(2));
    QObject* menu->setProperty("model", QVariant::fromValue(infos));
    ...

    @

    The problem is that this is not working - clicking on the menu bar button does not open the menu. As a side effect other menus also stop working.

    Similar code with QStringList is working fine. However i want to show one string as item text and pass a different string as item id for triggered event. Thats why I use Info object instead of single string per item

    What am I doing wrong?

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jens
      wrote on last edited by
      #2

      While I didn't test your code, it looks like you are setting the "model" property on the Menu when you should really be setting it on the "menuInstantiator" itself.

      See the bottom of http://qt-project.org/doc/qt-5/qml-qtquick-controls-menu.html for an example.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        shukurmukur
        wrote on last edited by
        #3

        Yes, my bad. I changed the code a lot and that code was not the initial code I was expecting to work.

        Originally on ApplicationWindow i declared alias property:
        @
        property alias menuModel: menuInstantiator.model
        @

        and in c++ I called:
        @
        QObject* root->setProperty("menuModel", QVariant::fromValue(infos));
        @

        However the important point I think is that the same code worked with QStringList, but not with QList<Object*>. Of course expression for MenuItem.text property should be different for QStringList and QList<Object*>, but I would expect only empty or incorrect texts in later case. Now menu is not showing at all

        1 Reply Last reply
        0
        • GianlucaG Offline
          GianlucaG Offline
          Gianluca
          wrote on last edited by
          #4

          I always get problem on passing QList<QObject*> to QML side too.
          I think that the problem is due to the fact that QML for some reason cannot properly see a custom QList instantiation.
          But, as you notice too, with QStringList everything works fine.
          So, my workaround to passing a complex object is to use a QStringList as a list of object IDs and use a slot for getting the corresponding QObject.
          Something like that:
          @
          Instantiator {
          id: menuInstantiator
          MenuItem {
          property InfoObject obj: backend.getInfoObject( modelData )
          text: obj.title || ""
          }
          }
          @
          where backend is a QObject globally visible to QML with a slot that return a QObject* given an QString id. And the modelData is one of the element of the QStringList that you pass from C++ to QML.

          Important: InfoObject has to declare the properties via Q_PROPERTY and to registered with qmlRegisterType otherwise QML cannot see it properly.

          1 Reply Last reply
          0
          • GianlucaG Offline
            GianlucaG Offline
            Gianluca
            wrote on last edited by
            #5

            Ah, I was forgetting... PAY ATTENTION TO THE OWNERSHIP OF RETURNING QOBJECT* :

            http://qt-project.org/doc/qt-5/qtqml-cppintegration-data.html

            It's an important aspect that if taken not seriously into account will crash your app.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              shukurmukur
              wrote on last edited by
              #6

              Thanks for the tips, Gianluca, it helped. Although it would be nicer if QList<QObject*> version worked

              1 Reply Last reply
              0
              • GianlucaG Offline
                GianlucaG Offline
                Gianluca
                wrote on last edited by
                #7

                I think that for get QList<QObject*> work we should file a feature request and to add a derived type QListObjects similar to QStringList and making it usable into QML as QStringList.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  shukurmukur
                  wrote on last edited by
                  #8

                  Well, I am not sure if QListObject is really needed as documentation suggests that QList<QObject*> should work: http://qt-project.org/doc/qt-5/qtquick-modelviewsdata-cppmodels.html. That makes me think that my case is either a bug or I am doing something stupid with the later being more likely as I am really new to QML and Qt.

                  1 Reply Last reply
                  0
                  • GianlucaG Offline
                    GianlucaG Offline
                    Gianluca
                    wrote on last edited by
                    #9

                    Humm... maybe we are both stupid... because I tried lot in the past and the QList<QObject*> never worked. That's why I developed the workaround I posted.
                    I'll do some further test.

                    1 Reply Last reply
                    0
                    • GianlucaG Offline
                      GianlucaG Offline
                      Gianluca
                      wrote on last edited by
                      #10

                      I discovered that template into the documentation:
                      QQmlListProperty

                      Maybe can be a solution for your problem.

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        shukurmukur
                        wrote on last edited by
                        #11

                        Thanks, I'll check this

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved