Reputation: 1
I try to use a kind of source code for Qt6, which in principle worked with Qt5: I want to make a graphical output for my system of hardcore particles. In the constructor of the QAbstractListModel I have two arguments: System *system, QObject *parent=0 I think the *system argument is the reason, why in the qml the item Hardcore_Entrymodel{} is not creatable (QQmlApplicationEngine failed to load component).
How can I make my qml File work again?
I ported the model stuff from a sheepflock simulation with qt5 which in principle worked. Now, with the new hardcore model and with qt6 the qml file errors. I did a recherche in the web and got a feeling, it errors because of the two argument constructor.
The Header File of Hardcore_Entrymodel:
class Hardcore_Entrymodel : public QAbstractListModel
{
Q_OBJECT
public:
explicit Hardcore_Entrymodel(System*, QObject *parent = 0);
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
void populate();
QHash<int, QByteArray> mPropertyNames;
enum mParticleProperties{
type = Qt::UserRole,
iparticle = Qt::UserRole+1,
size_semimajoraxis = Qt::UserRole+2,
size_semiminoraxis = Qt::UserRole+3,
x_mid_pxl = Qt::UserRole+4,
y_mid_pxl = Qt::UserRole+5,
xy_angle_degree = Qt::UserRole+6,
typecolor = Qt::UserRole+7,
};
Q_INVOKABLE void doNewStep();
Q_INVOKABLE void stepReady();
Q_INVOKABLE int returnWindowLx();
Q_INVOKABLE int returnWindowLy();
Q_INVOKABLE int returnSteptime_ms();
bool isNewStep();
void setIsNewStep(bool newS);
protected:
virtual QHash<int, QByteArray> roleNames() const override;
private:
System *hardcoresystem;
int nparticles;
InitQtView initqtview;
QList<std::tuple<std::string, int,int,int,int,int, QColor> > mDatas;
bool newStep;
signals:
void newStepDoing();
void newStepReady();
public slots:
void onNewStepDone();
};
The main function:
#include <QObject>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "Hardcore_InitClass.h"
#include "Hardcore_Entrymodel.h"
int main(int argc, char *argv[])
{
Hardcore_InitClass initClass(argc, argv);
System system;
initClass.return_Hardcoresystem_single(&system);
system.writeParametersFile();
QGuiApplication app(argc, argv);
// register the type DataEntryModel
// under the url "org.example" in version 1.0
// under the name "DataEntryModel"
qmlRegisterType<Hardcore_Entrymodel>("org.hardcoresystem", 1, 0, "Hardcore_Entrymodel");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/qt/qml/Main.qml")));
return app.exec();
}
And the first part of the qml file:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
//import QtQuick.Layouts 2.2
import QtQml.Models 2.12
import Qt.labs.qmlmodels 1.0
import org.hardcoresystem 1.0
Window {
id: appwindow
visible: true
width: hardcoreentrymodel.returnWindowLx()
height: hardcoreentrymodel.returnWindowLx()
Rectangle{
id: hardcoresystemrectangle
anchors.left: appwindow.left
anchors.top: appwindow.top
width: appwindow.width
height: appwindow.height
color: "white"
}
Hardcore_Entrymodel{
id: hardcoreentrymodel
//onNewPathDoing: console.log("New Path doing ...\n")
//onNewPathReady: {console.log("New Path ready ...\n")}
//onDataChanged: console.log("DataChanged received")
}
Timer {
id: steptimer
interval: Number(hardcoreentrymodel.returnSteptime_ms())
//interval: 100
repeat: true
running: true
triggeredOnStart: true
onTriggered: {hardcoreentrymodel.doNewStep()}
}
Item{
id: partilcesitem
width: hardcoresystemrectangle.width
height: hardcoresystemrectangle.height
anchors.left: hardcoresystemrectangle.left
anchors.top: hardcoresystemrectangle.top
Repeater {
[...]
kind regards, Tobias
Upvotes: 0
Views: 298
Reputation: 26096
QML requires that components that can be constructed with 0 or 1 explicit parameters. In the latter case, the first argument must be QObject*
parameter. The constructor choices you have are:
Hardcore_Entrymodel(QObject *parent = nullptr)
Hardcore_Entrymodel(QObject *parent = nullptr, System* system = nullptr);
Personally, I recommend you go with 1 and remove the System*
from your constructor since your solution requires you to instantiate and make System*
only available to one of your model instances.
Since your model is creatable, I feel that you need the System*
to be available to all your models, so therefore, I feel your System*
should be a static member. Doing so, means that it is initializable without an instance of your model.
// Hardcore_Entrymodel.h
class Hardcore_Entrymodel : public QAbstractListModel
{
Q_OBJECT
public:
explicit Hardcore_Entrymodel(QObject *parent = nullptr);
public:
// Static Methods
static void SetSystem(System* value) { g_hardcoresystem = value; }
static System* GetSystem() { return g_hardcoresystem; }
private:
// Static Member
static System *g_hardcoresystem;
};
Initialize your static member...
// Harcode_Entrymodel.cpp
System* Hardcore_Entrymodel::g_hardcodesystem = nullptr;
In your main.cpp you can populate your static member without needing to invoke the constructor.
/// main.cpp
int main(int argc, char *argv[])
{
System system;
Hardcore_Entrymodel::SetSystem(&system);
// ...
Upvotes: 0
Reputation: 1
From Stephen Quans idea, I made hardcoresystem to a static variable for all:
static System *hardcoresystem;
class Hardcore_Entrymodel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
public:
[..]
and in main:
int main(int argc, char *argv[]){
Hardcore_InitClass initClass(argc, argv);
System system;
initClass.return_Hardcoresystem_single(&system);
system.writeParametersFile();
hardcoresystem= &system;
QGuiApplication app(argc, argv);
[...]
Now, I think the Qt stuff should work. But, I have still to debug the communication between the qml file and the QAbstractListModel. This will take a bit time. But, thanks until here!
Tobias
Upvotes: 0