2017-08-03 100 views
0

是否有可能在运行时从C++创建ObjectModel?在运行时从C++创建ObjectModel

我有一个基于插件的应用程序,其中每个插件创建QQmlComponent和设置信号和槽然后给该组件到主应用程序用于呈现在ListView,对于该端我想有在c一个ObjectModel ++侧并在那里操纵它。

main.qml(主要的应用程序接口):

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 
     } 
    } 

} 

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 
     } 
    } 
} 

在第一次尝试,我想从C++侧访问MAINAREA项目,并呼吁与QQuickItem的addReport功能*从插件返回,没有运气。

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", &notificationModel); 

    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(); 
} 

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) 

Main app screenshoot

+0

那么如何定义ObjectModel?它究竟来自哪里? – dtech

+0

它来自[Qt库](http://doc.qt.io/qt-5/qml-qtqml-models-objectmodel.html)它是一个渲染其对象的标准模型。在我的情况下,我想渲染一些从应用程序插件发出的qquickitems。 –

+0

我的意思是它在插件的权利?你为什么要使用普通图书馆?有专门针对QML提供的'QQmlExtensionPlugin'顾名思义。 – dtech

回答

1

It is possible to create any QML object from C++,虽然99.99%病例是不好的做法,你不应该做,以及错误设计的指示,这些设计很可能会在稍后回来咬你。

应该创建或操作QML从C++对象,你应该是暴露于QML使QML对象可以与它交互的明确定义的C++接口。

无论你打算做什么,最有可能有更好的方法来做到这一点。向我们展示一些代码,以便我们可以给你一个更具体的答案。

+0

我编辑了文本并添加了一些代码,希望它能帮助您清楚地看到问题。 –