Text in Custom QQuickItem - qt

I am implementing a Custom QQuickItem which should be able to make a lineplot (x vs y). For performance reasons I did this using QSGNodes. I wonder what is the best way to implement the Text-Labels for the x-ticks (they should get set automatically according to the data range).
Should I use a QQuickPaintedItem or is there a way to do it via the QQuickItem?
Or is it possible to dynamically create text qml types ( http://doc.qt.io/qt-5/qml-qtquick-text.html) in my c++ file?

Don't over-complicate things by reinventing wheels. QML already has a Text type.
There is a downside - the decision to not have a public API to use the QML types from C++ in their C++ form. And I would not recommend creating QML objects from C++, it is just counterproductive.
Which means that your custom QML type will not be implemented purely in C++, you can implement the "core" stuff in C++ and still compose the complete type on the QML side, where you also get to use bindings, anchors, models, positioners, dynamic scoping and all that good stuff that is hard to do in C++.
This is not uncommon, lots of the stock QML controls are implemented this way - an abstract C++ core exposed to QML, where it is finished into a complete control in QML syntax.

Related

Qt6 C++ ownership of QObject when using QML_ELEMENT

I've started learning QML with Qt6 lately and am trying to apply "best practices" right from the start. When it comes to integrating C++ it seems that a family of macros (QML_ELEMENT and friends) is going to replace the old style *register functions. A best practices talk on the Qt youtube channel calls this "declarative registration". I've tried that in a small example using CMake and it practically worked out of the box.
Now to my knowledge C++ classes exported and instantiated within a QML module have "QML engine" ownership. Lets suppose I'd rather have C++ take ownership of my class and QML merely use it, how would I inform the QML engine about my instance? Do I need to use setContextProperty for that?
I've also wondered what benefits and drawbacks I'd get from letting either C++ or QML handle ownership? There seems to be hardly any information on those topics. I've even browsed a couple of Qt books and not a single one would elaborate on that...

Best way to send a QBitArray to QML App?

I'm quite a beginner in QtQuick, and I'm working on a small project where I have a C++ class (that I intend to register as a QML Type later) that, everytime my QML app feeds it some input, produce a QBitArray which gets read by QML and is outputted as a grid. (Basically, let's say I'm working on a 2D game with a board, where every cell has two possible states, and the list of states is produced by C++)
I'm wondering about the best way to make QML reads the BitArray. The most obvious solution to me would be to set it as a property, but QBitArray isn't a QObject (I guess I could inherit it and Qobject in a wrapper, but it feels unelegant).
I could also call a method of MyCLass wrapping the BitArray, but I'm wondering about threading overhead. If my object has been created in QML/JS, will there be overhead to call its C++ methods ?
So, in conclusion, what is the most elegant/efficient/idiomatic way to do this ?

Qt's unique patterns

I am working at the moment with Qt and discovered signals and slots. I think this is a Qt specific pattern. I am wondering if there are more Qt specific patterns like signals and slots. Are there any? Is there any specification about them?
In addition:
Qt's specific pattern are splitted in two parts:
Qt providing special classes for using design patterns like the Qt Quick module, Signal Slots..
The second part is the structure of some classes for example: QWidget
QWidget inherits from QObject which implements the composite pattern.
For further information i recommend this book: http://www.amazon.de/Introduction-Patterns-Prentice-Software-Development/dp/0132826453
There are some features which are unique to Qt or at least few implementations exist in other languages.
To name a few other than the signal-slot mechanism :
The Qt Quick module : Enables you to write QML applications and provides everything needed to create a rich application with a fluid and dynamic user interface. Some features are The Visual Canvas, User Input, States, Transitions And Animations, Particles And Graphical Effects, ...
Qt's Undo Framework : It's based on command pattern for implementing undo/redo functionality in applications.
The State Machine Framework : Can be used to effectively embed the elements and semantics of statecharts in Qt applications. It integrates with Qt's meta-object system; for example, transitions between states can be triggered by signals, and states can be configured to set properties and invoke methods on QObjects.

How to efficiently expose many C++ data members of a single object to QML?

I have a C++ object pointer with many data members. I need them all available in QML. One obvious way would be to create a Q_PROPERTY for each member so they can be individually accessed via QML. However, if we are talking about dozens of data members, well that's a lot of lines of Q_PROPERTY, not to mention having to individually handle these in QML as separate properties as well (especially if dealing with "on changed" signals for each property).
I am wondering if it is possible to make a single Q_PROPERTY that would include all the data members I need. But what is not clear to me is the apparent mismatch between the types that QML supports and the types you can list in a Q_PROPERTY. For example, in QML, we have a basic string but its corresponding lising in a C++ Q_PROPERTY must be QString:
Q_PROPERTY(QString datastring READ showdata NOTIFY datastringChanged)
//in QML, `datastring` is just a plain string
Would there be more complex properties like lists or arrays that can be easily matched? QML has a list type and C++ has the QList but are these the same thing? Where can I find a listing of compatible types between C++ and QML?
On the other hand, having individual Q_PROPERTY for each data member could likely be better performance (my data is large and often changing) since the QML would not need to parse anything, perhaps.
Would there be more complex properties like lists or arrays that can
be easily matched? QML has a list type and C++ has the QList but are
these the same thing? Where can I find a listing of compatible types
between C++ and QML?
Have a look at the C++/JS data conversion help page. I think the list missed that QList<QObject*> is also possible.
On the other hand, having individual Q_PROPERTY for each data member
could likely be better performance (my data is large and often
changing) since the QML would not need to parse anything, perhaps.
Maybe, yes, depends on your performance needs. A C++ QList gets converted to a JavaScript list when accessed from QML/JS. That's a bit of conversion overhead indeed. Also, ff an item in the list changes, you need to emit the notify signal for the complete property, and every JS binding in which the list was used needs to be reevaluated, which will again be many list conversions. That could be better by having more fine-grained properties, but it really depends.
Btw, with Qt 5.1 there now is MEMBER, which makes writing Q_PROPERTYs a bit easier.

How to use Qt Model/View framework with the Graphics View framework

I am working on a mapping application and need to display the data objects using a table, a form and as graphical objects in the map. I'm using PyQt, but that's not really important as this is a Qt question not a Python question.
If I only needed the table and form views this would be easy, I'd just use the Qt Model/View framework. However I need the map view to provide functionality only really available using the Graphics View framework, which is essentially it's own Model/View framework with the QGraphicsScene acting as the data model.
I can think of two ways to do this. One would be to start with an authoritative model subclassed from QAbstractItemModel, link it to a subclass of QAbstractItemView and from there generate and update QGraphicsItems in the scene. This looks ugly though because I'm not sure how to handle user interaction with and changes to the data items though interaction with the QGraphicsItems.
The other way I can think to do it is to treat the QGraphicsScene as the authoritative data source, storing the data object in each QGraphicsItem's .data() property. I'd then subclass QAbstractItemModel and write it so that it accesses the data in the scene as it's data store, the other views would then use this as their model. How would I propagate changes to the data in the scene up to the model though?
Whichever approach I take, it looks like there's a gap not handled by the frameworks. In Model/View all changes are assumed to be made in the model. In Graphics View all changes are assumed to be made in the scene.
So which approach would you choose QAbstractItemModel(authoritative)->QAbstractItemView->QGraphicsScene or alternatively QGraphicsScene(authoritative)->QAbstractItemModel->Other Views. Why would you choose one over the other and what gotchas do you anticipate? Has anyone else needed to bridge this gap between Qt's twin model/view frameworks and how did you do it?
QAbstractItemModel(authoritative)->QAbstractItemView->QGraphicsScene
Without a doubt. I have done this before, it does require a bit of duplication (at least some that I couldn't avoid) but nothing too bad.
This also allows you to represent your data in standard views along with the scene which is quite nice.
My best advice would be to store a QHash of QPersistantModelIndex to QGraphicsItem and a QGraphicsScene in the QAbstractItemView you create. This allows you to quickly go between Model/View land (QModelIndex) to Graphics View land (QGraphicsItem)

Resources