Est-il possible de créer un ObjectModel à partir de C++ lors de l'exécution?Création d'ObjectModel à partir de C++ à l'exécution
J'ai une application à base de plug-in, où chaque plug-in créer un QQmlComponent
et la configuration du signal et des fentes, puis donner le composant à l'application principale pour le rendu dans un ListView
, pour cette fin, je veux avoir un ObjectModel
dans le C++ côté et le manipuler là.
main.qml (interface principale de l'application):
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
ApplicationWindow {
id: qmlMainWindow
width: 1240
height: 720
minimumWidth: 270+600
minimumHeight: 120+400
visibility: "Maximized"
visible: true
title: "CTC - Tableau de bord"
GridLayout {
anchors.fill: parent
columnSpacing: 0
rowSpacing: 0
columns: 2
rows: 2
HeaderArea {
id: headerArea
Layout.row: 0
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.fillHeight: true
Layout.minimumHeight: 120
Layout.maximumHeight: 120
}
NotificationArea {
id: notificationArea
Layout.row: 1
Layout.column: 1
Layout.fillHeight: true
Layout.maximumWidth: 350
Layout.preferredWidth: 300
Layout.minimumWidth: 270
model: notificationModel
}
MainArea {
id: mainArea
bgColor: "lightgray"
Layout.row: 1
Layout.column: 0
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
élément MainArea:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQml.Models 2.1
Item {
objectName: "mainArea"
function addReport(obj) {
omodel.append(obj);
}
property alias bgColor: mainAreaBackground.color
property ObjectModel omodel
Rectangle {
id: mainAreaBackground
anchors.fill: parent
color: "white"
ListView {
anchors.fill: parent
model: omodel
}
}
}
Au premier essai, je voulais accéder à l'élément MainArea de C++ côté et appeler la fonction addReport avec QQuickItem * retourné d'un plugin, sans chance.
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>
#include <QtPlugin>
#include <QPluginLoader>
#include <QDebug>
#include <QtQmlModel>
#include "notificationmodel.h" // model used in the notification area
#include "interfaces/inotification.h" // interface for a plugin
#include "interfaces/ireport.h" // interface for a plugin (of interest for this post)
int main(int argc, char *argv[])
{
QGuiApplication::setApplicationName("ctc_dashboard");
QGuiApplication::setOrganizationName("CTC");
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication a(argc, argv);
NotificationModel notificationModel(&a);
QQmlApplicationEngine engine;
QPluginLoader ploader; // I load the plugin which his task is to connect
// to a QtRemoteObject on some server and create a QQuickItem
// which will present some statistics.
ploader.setFileName("plugins/affair_states/AffairStates.dll");
engine.rootContext()->setContextProperty("notificationModel", ¬ificationModel);
engine.load(QString("%1/%2")
.arg(QGuiApplication::applicationDirPath())
.arg("qml/main.qml"));
if (engine.rootObjects().isEmpty())
return -1;
if(ploader.load()){
IReports* plugin = qobject_cast<IReports*>(ploader.instance());
if(plugin) {
qDebug() << "Good plugin : " << plugin->name();
QObject::connect(plugin, &IReports::notify, [&](NotificationModel::Notification n){
notificationModel.addNotification(n);
});
QObject::connect(plugin, &IReports::newReport, [&](QQuickItem* i){
qInfo() << "Signal recived";
qDebug() << "New report " << i;
qInfo() << engine.rootContext()->contextObject()->findChild<QObject*>("mainArea");
qInfo() << "Omodel " << engine.rootContext()->contextProperty("omodel");
});
}
}
return a.exec();
}
interface plug-in iReport:
#include <QtPlugin>
#include "inotification.h"
#include <QQuickItem>
class IReports: public INotification
{
Q_OBJECT
public:
IReports();
virtual ~IReports();
virtual QList<QQuickItem*> reports() = 0;
virtual QString name() const = 0;
virtual QString sectionName() const = 0;
signals:
void newReport(QQuickItem* report);
};
#define IReports_iid "dz.ctc.dashboard.interfaces.IReports"
Q_DECLARE_INTERFACE(IReports, IReports_iid)
Alors comment est défini ObjectModel? D'où vient-il exactement? – dtech
il vient de la [bibliothèque Qt] (http://doc.qt.io/qt-5/qml-qtqml-models-objectmodel.html) c'est un modèle standard qui rend ses objets. et dans mon cas je veux rendre quelques qquickitems qui sont émis à partir des plugins de l'application. –
Je veux dire que c'est dans le plugin, n'est-ce pas? Pourquoi utilisez-vous une bibliothèque régulière? Il y a le 'QQmlExtensionPlugin 'dédié qui, comme son nom l'indique, est spécialement pour QML. – dtech