1
votes

My goal is to describe a qml item in a qml file and then use a corresponding C++ class to add to the visual representation of this item.

I know it is possible to describe a qml item and use it in qml file and the communicate with it from c++ through signal/slots.

I also know it is possible to describe a qml item in C++ using QQuickPaintedItem and use it in a qml file (making it available through the register mechanism). Are there other ways?

So, the actual question is it possible to combine both in one item? So, I want to have a qml item and a c++ class painting the same area, e.g. I have specific OpenGL code in c++ and a usual Rectangle Frame with MouseArea defined in qml.

1
Create your own item in C++. C++ is compiling language, qml is interpreted (in runtime), so it is not possible to use qml definitions in compile-time.Dmitry Sazonov
With QQuickPaintedItem I am able to use C++ objects in qml. With object->findChild<QObject*>("myobject") I can use qml objects in C++. The question is, whether there is an object which is like QQuickPaintedItem but also can have a qml visual representation. The qt.labs.templates seem interesting.PsiX
You can combine C++ and QML in a single element by putting your QQuickPaintedItem-derived element above your QML element. You can do that by adjusting the z property or just by ordering the elements accordingly in a single QML file. Since QQuickPaintedItem has transparent background, you will see your drawing output from both C++ and QML.Andrej Repiský
Just add stuff to it in QML: MyPaintedItem { Rectangle{} } and save it into MyPaintedItemWithRectangle.qml. Then use the MyPaintedItemWithRectangle type.Velkan
@Velkan This doesn't help with the rendering in code.PsiX

1 Answers

0
votes

After the hint from Andrej I decided to realize my goal of having both the qml representation and a C++ rendering class by creating a wrapper class which derives from QQuickPaintedItem and by this overriding the paint method. With this I can render into the item in code. The item is used in my main qml file.

It is a wrapper class because it loads the qml file I want to show through a QQmlComponent which creates the QuickItem I want to show, too. I do this by setting the parent of the loaded/created item to my wrapper class. So in my QuickPaintedItem class (best done in classbegin, when engine is already initialized):

QQmlComponent component(engine,QUrl("qrc:/myqml.qml")); QObject* object = component.create(); QQuickItem* quickItem = qobject_cast<QQuickItem*>(object); quickItem->setParentItem(this);

Then myqml.qml is rendered and my paint method, too. And I have a central place where I can use both.

After the comments from Velkan, another way is to put the loading of the component in a Loader qml item:

Wrapper { Loader{ onQmlChanged: source = newQml } }

where onQmlChanged would be a slot which consumes a signal:

signal onQmlChanged(string newQml);

I cannot say which way is better performance wise. Defining the structure in qml seems easier and cleaner. A difference to the code version, is that it loads the item at creation time of the Wrapper, so during the creation of the main.qml and before it is shown.