Important: Please read the Qt Code of Conduct -

How to create an Item from C++ (without QML?)

  • Hi,

    I was wondering if someone could tell me if there is a way to instance a QDeclarativeItem (class A, for example) from C++ without using QML and add sub-items to it (like for example MouseArea etc.)
    Let me explain a bit more. I know two ways to instance a QDeclarativeItem subclass:
    -Either just instance it simply with
    A* a = new A();
    Like normal variables
    -Or, sing a QML file (and in that case I need the view)
    QDeclarativeComponent comp (view->engine(),QUrl("file.qml"));
    A* a = aobject_cast<A*>(comp.create());
    And then the creation uses the default constructor of the class A and loads all the content from the QML file.

    The problem of the first solution is that I want my class A to have a MouseArea on it, so, it seems l'ike I need a QML to describe it. But, the problem with the second solution is that I absolutelly need do make a Factory of A's (a static method in tha class A that takes the view as a parameter). This is quite anoying because in fact the instances of this item are created by another item (in my program) and this item doesn't know about the view (so I have to change a lot o things in my current code to do that....).

    What I was wondering is if there is a n intermediate solution.
    Can I instance an A object like this:
    A* a = new A();

    and somewhere, in the code of the A class put the sub-items I want (such as MouseAreas to make my item clickable?)
    May be some thing like this:
    A::A(){ //constructor
    this->addSubItem(MouseArea m); //but does not exist, I believe...
    I havent found any method on the documentation to do that, and I believe there is no way to instance a MouseArea...

    So, any suggestions, please?

    Thank you all!

  • There is no documentation and the API is private and extremely messy and unintuitive to work with.

    I think you must use the QMetaType::construct factory function to instantiate QML components in C++

    @void * QMetaType::construct(int type, void * where, const void * copy)@

    You can also "vote for a native public API here": ;)

  • You can use existing QDeclarativeItem classes as for instance QDeclarativeMouseArea just like any other by including the header (<code>QtDeclarative/private/qdeclarativemousearea_p.h</code>) and exporting the class to the declarative library (you do not have to, and even cannot, use the meta type system as the items beeing a QObject are non-copyable and therefore non-constructible).

    Be aware that this will void any binary compatibility promises (although the QDeclarativeItem classes are very unlikely to change now).

    But maybe you do not even need to do that. What is your initial requirement? Why don't you use QML to declare your item in the first place? What about a global <code>ComponentFactory</code> which is initialized with the QDeclarativeEngine once and used to create components from basically anywhere in your code?

  • Hi, sorry for the late answer I have been working in other parts of my projects where I hav had big issues ( ) that are blocking me.

    Well, what utcenter said looks quite hard to me. Since I want to keep it as simpler as possible, I have decided to avoid to include the qdeclarativemouse file. So, I have done a factory as you Likas Geyer said (I pass the view as a parameter in order to use its engine and avoid creating meny useles engines).

    Thank you anyway for the answers :)

  • It's not just hard, it's impossible - but fortunately totally unnecessary ;-)

    The items are just private by default to relieve them from binary compatibility promises, there is nothing special to them.

    Anyway, you're weclome. Feel free to prepend to thread title with '[Solved]... ' to indicate that there is a solution inside.

Log in to reply