Possible to wrap non-QObject C++ object by an Entrymodel?
-
Hallo,
I still want to wrap a C++ object by an Entrymodel. The C++ object is a Particle System which I want to order time steps. I want that every state of the C++ object is preserved by the Entrymodel constructur. If I init the Particle System in the Entrymodel constructor it freezes at the initial state. So I started with Qt5 and an overloaded constructor for the Entrymodel - the parameters were (QObject, System*).
This worked for me in Qt5, but not in Qt6. I already did a Post. But there was no good solution for me presented:
Qt6 QAbstractListModel - constructor with two arguments - qml Element is not creatableSo, is there a way at all to wrap a non-QObject C++ Object in an Qt Entrymodel?
Kind regards,
Tobias -
We don't know your code, so we can't say whether it works or not.
The QML element has to be default constructable. In your case, there is no default c'tor. Just one with two arguments. That's the issue. -
@Axel-Spoerl Dear Axel Spoerl,
... and I cannot make the constructor with two arguments to the default constructor? In Qt5 this worked for me. I want to wrap my System* pointer, because the current state of the system is transferred by the constructor.
I presented some (complicate) code in stackoverflow:
Qt6 QAbstractListModel - constructor with two arguments - qml Element is not creatable -
I dont know the working example in Qt5 not well anymore, because it was another simulation which I modified since that.
But must the System* pointer to be a virtual class member of the entrymodel? If I compile Qt programs there is some virtualizaion, isn't it? -
@Tobias83 said in Possible to wrap non-QObject C++ object by an Entrymodel?:
... and I cannot make the constructor with two arguments to the default constructor?
That's a contradiction in itself. A default constructor must be callable without arguments.
The QML engine creates qml elements by calling its default constructor without arguments. That's not possible in your case, which is what the error says. I actually doubt that it worked in Qt5, but feel free to prove me wrong.
-
I'm still not sure what your actual need is after reading this post and your previous one.
Are you sure you want the object to be instantiated by QML, can't you instantiate it in C++ and expose to QML as singleton?
If you need it to be instantiated by QML with some parameters, can't you use properties for that instead?I'm also having a hard time seeing how this could have worked in Qt 5, not much has changed on this subject.
-
I want to write a particle simulation of hard spheres. Therefor I want to get out two executebles: one fast without Qt and without graphical output, and one with Qt and with graphical output. For the second I want to wrap the System class of the first as a pointer in the Entrymodel and draw the spheres by QML.
-
A question for understanding Qt: As I understood, there is a continuous process generating the Entrymodel object by its QObject parent, right? So if I have a constructor Entrymodel(QObject parent*), the previous state of the Entrymodel (parent) is parameter for the next, right? And this happens in a continuous loop?
-
@Tobias83
I know nothing about QML orEntrymodel
, so excuse me if there is something special about that. But speaking for Qt at least there is no "continuous process generating" anything, and theparent
argument to aQObject
constructor simply sets up the object model hierarchy for parent/child, there is no "copying of state" between parent & child (unless you code something yourself). -
@Tobias83 Is
Entrymodel
something specific to your project? I can't see anything related to Qt with this name. If it is something specific, nobody here is going to know what this is. It is difficult to understand what you are asking about. Is there any way that you can try to extract the essence of the issue that you are having without discussing specific details of your application? To me, it feels like there is probably a solution to what you want to do but we need a better way to understand it. -
@Tobias83 OK, so
Entrymodel
is just part of the name of your class which implements aQAbstractListModel
.How is your list model used in your application? If you want to expose it to QML so that you can actually instantiate it in QML, like this
ListModel { model: Hardcore_EntryModel { } ... }
then you are restricted to not being able to pass arguments into your constructor.
On the other hand if you want to be able to instantiate your model in C++ and just make that instance accessible in QML, you are potentially less restricted. In your C++ you can instantiate your
Hardcore_EntryModel
however you want and useqmlRegisterSingletonInstance
:Hardcore_EntryModel entryModel(arg1, arg2, ...); qmlRegisterSingletonInstance("mytypes", 1, 0, "EntryModel", &entryModel);
and then use it in your QML:
ListModel { model: EntryModel // use the singleton instance exposed in the C++ ... }
-
@Bob64 Dear Bob64,
How do I have to handle this contructor:explicit Hardcore_Entrymodel(QObject *parent=0, System* system);
Is the =0 correct?
If I call it like this, it errors:tw_hardcoresystem::Hardcore_EntryModel entryModel(nullptr, &system);
It also errors with this constructor, because there is a QAbstractListModel(parent) which needs the parent argument:
explicit Hardcore_Entrymodel(System* system);
Thank you for your Help!
Tobias
-
@Tobias83 said in Possible to wrap non-QObject C++ object by an Entrymodel?:
explicit Hardcore_Entrymodel(QObject *parent=0, System* system);
Per C++, any optional/default-value parameters can only come after any mandatory ones. Your code is not legal because a parameter without a default comes after one with a default. Either give a default for
System* system
as well, or (preferable IMO) make thesystem
parameter come before theparent
one. I would always leave aQObject
-derived constructor takingQObject *parent = nullptr
as the last argument. -
@Tobias83 I now found an a little bit different solution. In stackoverflow someone suggested set and get functions. So I have:
public: explicit Hardcore_Entrymodel(); //explicit Hardcore_Entrymodel(QObject *parent, System* system); void setSystem(System* system);
and in the main fct:
Hardcore_Entrymodel entryModel; entryModel.setSystem(&system); qmlRegisterSingletonInstance("hardcoresystem", 1, 0, "Hardcoreentrymodel", &entryModel);
For this, it draws a window and the "QML Object is not creatable" error disappears.
But there are still some little mistake, which are not related to Qt, I think.
Thanks a lot until here!!!
kind regards,
TobiasPS: if the std::stof function in one case outputs the double value of a string, and some loops later gives the integer value - it is not related to Qt? What can this be? A corrupt compiler?
-
@Tobias83
std::stof()
has nothing to do with Qt, you do not have a "corrupt compiler" and even if you did that would not change its behaviour according to how many times it is called. It returns afloat
. It does not return anint
, though of course a value returned might happen to be an integer (as in, no decimal places). -
Does the QAbstractListModel work the same as Singleton if data is changed. In QML I have a Repeater which draws the particles. But if I do a simulation step, the picture in in the window is not updated, but the coordinates in cpp are. On the console I get the output qml: DataChanged received.
This my step method:
void Hardcore_Entrymodel::doNewStep() { emit newStepDoing(); hardcoresystem->testStep(); populate(); return; }
and populate looks like that:
void Hardcore_Entrymodel::populate() { int ipart; for(ipart=0; ipart<nparticles; ipart++){ mDatas[ipart]= initqtview.SystemToWindow(hardcoresystem->returnIParticle(ipart)); } emit dataChanged(index(0),index(nparticles)); return; }
And the step is made by mouseclick in qml:
MouseArea { anchors.fill: parent onClicked: Hardcoreentrymodel.doNewStep() }