Equivalent to QGraphicsView and QGraphicsScene?
-
Hello people, I'm trying to create a QML desktop app based on an existing app built with Widgets. It is a dashboard-like app where you can drag and place "tiles" of different functions freely on a whiteboard. The general hierarchy was something like this: QGraphicsView<-QGraphicsScene<-QGraphicsRectItem<-QWidget
I'm new to QML and have done a little bit of searching around, but I haven't got a good idea as to how, or if it's possible, to implement this in QML. It'd be very helpful if you could point me to some specific Items that can be used here. Thanks in advance.
If it helps to visualize what I'm trying to build, here is a simple sketch:
-
Hi @SWMCODER, and welcome!
I suggest you start by opening Qt Creator's "Examples" pane and searching for Qt Quick Examples - Drag and Drop. Build it, run it, and try it out.
-
@JoeCFD I use QML Canvas to draw some basic shapes. Not sure if it is good enough for you.
For complicated geometries, you may need
https://doc.qt.io/qt-6/qtquick-visualcanvas-scenegraph.htmlBut the license of this module is GPL, not LGPL.
https://doc.qt.io/qt-6/qtgraphs-index.html#licenses-and-attributions -
Basically, you can prepare a set of QML files (e.g. for basic shapes), and load them dynamically from C++ using something like
QQmlComponent component(engine, fileName); QVariantMap propertyMap; // Here you can add properties to the map that you want to set to the newly created component, e.g. a position QQuickItem* pItem = dynamic_cast<QQuickItem*>(component.createWithInitialProperties(propertyMap)); // Add to the correct parent, which is e.g. your QML root item
Note: This is probably not the idiomatic QML way of doing things, because it means you manage your scene from C++. It's a very flexible way though.
A potentially simpler way is this:
- Choose a set of basic primitives (Rectangle, Ellipse, Polyline, ...)
- Create a model for each primitive (list model should be fine) - you can do this in C++ or in QML
- Create a Repeater for each model - it will display all the items currently in the model
- Adding a new item to a model will automatically display it
- Make sure you can set important properties via model - position, size, color,...
-
Using a single c++ model with a Repeater + DelegateChooser would be the idomatic and simpler way.
-
In general, I see little benefit by hosting a widget application (with CPU rendering) in a QML wrapper.
If you want to experience the power of Qt Quick / Quick controls, better refactor the application and benefit from GPU rendering boosting your drag & drop stuff. If that's too much / not necessary: Why not stay in widgets?