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. [SOLVED] parameter in constructor of a custom qquickitem
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] parameter in constructor of a custom qquickitem

Scheduled Pinned Locked Moved QML and Qt Quick
12 Posts 2 Posters 16.6k 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.
  • M Offline
    M Offline
    matteli
    wrote on last edited by
    #1

    Hello,

    I used :
    @qmlRegisterType<MyClass>("MyLib", 0,1, "MyClass");@
    to used my class as a custom item in qml.

    It works fine.

    But now i would like to use the same class but i want to pass parameter to the constructor of the class.
    How can i used the qmlRegisterType for this.

    Thanks

    matteli

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Add a default value to that new parameter, so that QML engine can discard it when generating meta objects. When constructing the object by hand in JavaScript or C++, that parameter will still be available.

      (Z(:^

      1 Reply Last reply
      0
      • M Offline
        M Offline
        matteli
        wrote on last edited by
        #3

        Thanks for attention.
        But i want a parameter in the qml instance of my class.
        I put a piece of my code illustring the problem.

        main.ccp
        @
        #include <QGuiApplication>
        #include "map.h"
        #include "model.h"
        #include <thread>
        #include "message.h"
        #include <QQuickView>

        int main(int argc, char *argv[])
        {
        unsigned int width = 1024;
        unsigned int height = 608;

        QGuiApplication app(argc, argv);
        
        Model model;
        model.moveToThread(&model);
        model.start();
        
        qmlRegisterType<Map>("Histemul", 0,1, "Map");
        
        QQuickView view;
        
        view.setSource(QUrl::fromLocalFile&#40;"ui.qml"&#41;);
        view.setClearBeforeRendering(false);
        
        view.show();
        
        
        return (app.exec());
        

        }
        @

        ui.qml
        @
        import QtQuick 2.0
        import Histemul 0.1

        Item {
        Map {
        fill: "land"
        ...
        }
        ...
        }
        @

        With that, there is no problem. But now i want to pass to the constructor of the class Map the object model and i want to access model in the object constructed in qml.

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          There is no mechanism in QML that I know of that would allow you to do that. You need to change your approach: for example, add a new Q_INVOKABLE method like "initialise()" to your c++ class, and then in QML call:
          @
          Map {
          Component.onCompleted: {
          initialise();
          }
          }
          @

          This will fill your object. Another approach would be to use a singleton and access it in the default constructor.

          (Z(:^

          1 Reply Last reply
          1
          • sierdzioS Offline
            sierdzioS Offline
            sierdzio
            Moderators
            wrote on last edited by
            #5

            Or just use the Q_PROPERTY setter to adapt every time "fill" changes.

            (Z(:^

            1 Reply Last reply
            0
            • M Offline
              M Offline
              matteli
              wrote on last edited by
              #6

              But in all your approch, the class Map can't access "model" object declared in the main function. When i changed the fill, i used setFill Q_PROPERTY but in this function, i need to acess to the "model" object.

              Before used the qquickitem, i have tried to use QQuickWindow::beforeRendering() signal to connect with the painting function but because of problem, i prefered used qquickitem.
              When i have tried this, my constructor was :
              @
              Map::Map(int width, int height, int initialBlock, const QUrl & source, Model & model): QQuickView(source) , mWidth(width), mHeight(height), mTopLeftBlock(initialBlock), mModel(model)
              @
              but the qquickitem needs a defaut constructor

              I tried the singleton but it doesn't seems to work.

              The only approch i see for the moment is to use a double signal/solt connected.
              One signal when i'm in the setFill function connected to a slot in my function in Model class and at the end of the function a signal connected to a slot to a function in the Map Class.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                matteli
                wrote on last edited by
                #7

                The double signal/slot will not work because i can't access the object Map instanced in the qml code.

                1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  [quote author="matteli" date="1357994339"]The double signal/slot will not work because i can't access the object Map instanced in the qml code.[/quote]

                  You need to set object name:
                  @
                  // QML
                  Map {
                  objectName: "myName"
                  }

                  // C++
                  parent->findChild("myName");
                  @

                  Why didn't the singleton work? You should make Model class into a singleton and then it would be available in every place that has it's header included.

                  (Z(:^

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    matteli
                    wrote on last edited by
                    #9

                    Ah ok, i tried a singleton with the class Map.

                    What do you think to use setContextProperty for exposing the model object to qml code ?

                    1 Reply Last reply
                    0
                    • sierdzioS Offline
                      sierdzioS Offline
                      sierdzio
                      Moderators
                      wrote on last edited by
                      #10

                      You can do that if you wish, too. I don't know your app, so I can't say if it's required. Sometimes it's enough just to have it in c++, sometimes it's needed in QML, too.

                      (Z(:^

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        matteli
                        wrote on last edited by
                        #11

                        ok i resolve my problem. I give a solution for others which have this problem.

                        Objective : Give access to a object (named : model) for a qquickitem (named : map).

                        Problem : for using a class as a custom quickitem, you must used qmlRegisterType which only support defaut constructor for the class. There is no possible to give a reference to model during the construction of map in qml code.

                        My solution according to sierdzio suggestion :

                        main.cpp
                        @
                        #include <QGuiApplication>
                        #include "map.h"
                        #include "model.h"
                        #include <thread>
                        #include <QQuickView>

                        int main(int argc, char *argv[])
                        {
                        QGuiApplication app(argc, argv);

                        Model model;
                        model.moveToThread(&model);
                        model.start();
                        
                        qmlRegisterType<Map>("MyLib", 0,1, "Map");
                        
                        QQuickView view;
                        
                        view.setSource(QUrl::fromLocalFile&#40;"ui.qml"&#41;&#41;;
                        view.setClearBeforeRendering(false&#41;;
                        
                        /* After the construction of map in QML code, i continue the init here*/
                        Map* map = rootQml->findChild<Map *>("map");
                        map->init(model);
                        
                        view.show();
                        
                        return (app.exec&#40;&#41;&#41;;
                        

                        }

                        @

                        map.h
                        @
                        #ifndef MAP_H
                        #define MAP_H
                        #include "model.h"
                        #include <QQuickItem>

                        class Map : public QQuickItem
                        {
                        Q_OBJECT

                        public:
                        Map();
                        ~Map();

                        void init(Model &model);
                        

                        private:
                        //members
                        Model *mModel;

                        //methods
                        QSGNode *updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * updatePaintNodeData);
                        

                        };
                        #endif // MAP_H
                        @

                        map.cpp
                        @
                        Map::Map()
                        {
                        setFlag(QQuickItem::ItemHasContents, true);
                        }

                        Map::~Map()
                        {
                        delete mModel;
                        }

                        void Map::init(Model &model)
                        {
                        mModel = &model;
                        return;
                        }
                        @

                        ui.qml
                        @
                        import QtQuick 2.0
                        import MyLib 0.1
                        Item {
                        Map {
                        id: map
                        objectName: "map"
                        }
                        }
                        @

                        Thank you sierdzio

                        1 Reply Last reply
                        0
                        • sierdzioS Offline
                          sierdzioS Offline
                          sierdzio
                          Moderators
                          wrote on last edited by
                          #12

                          I'm happy you have found a solution. Please add [Solved] to the beginning of your topic's title. I've already tagged it as solved for you.

                          (Z(:^

                          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