[SOLVED] parameter in constructor of a custom qquickitem



  • 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


  • Moderators

    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.



  • 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.


  • Moderators

    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.


  • Moderators

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



  • 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.



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


  • Moderators

    [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.



  • 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 ?


  • Moderators

    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.



  • 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


  • Moderators

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.