Put C++ class into QML window



  • I have such problem: I create C++ class and bind it with QML. Then I register it using qmlRegisterType() and create. But! When I launched application I observe that it was created as separate window instead of be placed into main.qml file. What should I do to place my class into main.qml like some Rectangle or text?

    Here is code listing.

    BaseObject.h

    @#ifndef BASEOBJECT_H
    #define BASEOBJECT_H

    #include <QObject>
    #include <QtGui>
    #include <QtCore>
    #include <QMainWindow>
    #include <QGraphicsObject>

    #include <QtDeclarative>
    #include <QDeclarativeContext>
    #include <QtDeclarative/QDeclarativeView>

    class BaseObject : public QObject
    {
    Q_OBJECT
    public:
    explicit BaseObject(QObject *parent = 0);

    Q_PROPERTY(int x READ getX WRITE setX NOTIFY xChanged FINAL)
    Q_PROPERTY(int y READ getY WRITE setY NOTIFY yChanged FINAL)
    Q_PROPERTY(int resources READ getResources WRITE setResources NOTIFY resourcesChanged FINAL)
    Q_PROPERTY(int resIncrement READ getResIncrement WRITE setResIncrement NOTIFY resIncrementChanged FINAL)
    
    int getX(){return _x;}
    int getY(){return _y;}
    int getResources(){return _resources;}
    int getResIncrement(){return _res_increment;}
    
    
    void setX(const int &n){_x = n; emit xChanged();}
    void setY(const int &n){_y = n;emit yChanged();}
    void setResources(const int &n){_resources = n;emit resourcesChanged();}
    void setResIncrement(const int &n){_res_increment = n;emit resIncrementChanged();}
    

    signals:
    void xChanged();
    void yChanged();
    void resourcesChanged();
    void resIncrementChanged();

    public slots:

    private:
    int _x;
    int _y;
    int _resources;
    int _res_increment;

    QDeclarativeView *ui;
    

    };

    #endif // BASEOBJECT_H@

    BaseObject.cpp

    @#include "baseobject.h"

    BaseObject::BaseObject(QObject *parent) :
    QObject(parent)
    {
    ui = new QDeclarativeView;
    ui->rootContext()->setContextProperty("context", this);
    ui->setSource(QUrl::fromLocalFile("qml/PlanetWars/BaseObject.qml"));

    setX(0);
    setY(0);
    setResources(100);
    setResIncrement(1);
    
    ui->show();
    

    }@

    BaseObject.qml

    @// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
    import QtQuick 1.1

    Rectangle
    {
    width: 150
    height: 150
    opacity: 1

    Image
    {
        id: image1
        x: 0
        y: 0
        width: 150
        height: 150
        source: "nebula.jpg"
    }
    

    }@

    main.cpp

    @#include <QtGui/QApplication>
    #include "qmlapplicationviewer.h"
    #include "baseobject.h"

    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
    QScopedPointer<QApplication> app(createApplication(argc, argv));

    qmlRegisterType&lt;BaseObject&gt;("Library", 1, 0, "BaseObject");
    
    QmlApplicationViewer viewer;
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile&#40;QLatin1String("qml/PlanetWars/main.qml"&#41;);
    viewer.showExpanded();
    
    BaseObject b_o;
    
    
    return app->exec&#40;&#41;;
    

    }@

    main.qml

    @// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
    import QtQuick 1.1
    import Library 1.0

    Rectangle
    {
    width: 500
    height: 500

    MouseArea
    {
        x: 1
        y: 0
        anchors.rightMargin: -1
        anchors.bottomMargin: 0
        anchors.leftMargin: 1
        anchors.topMargin: 0
        anchors.fill: parent
    }
    

    }
    @


  • Moderators

    That is very wrong. You get 2 windows, because you create 2 UIs (QmlApplicationViewer, and your BaseObject are both QDeclarativeViews). If you want to add your base object as a C++ backend, you should remove all "ui" code from that class, and register it in main.cpp with ::setContextProperty. if you want to have base object as a QML item, you have to make it subclass QDeclarativeItem (but AFAIK, that is not what you want to do).



  • Hello,
    I don't really understand what you are trying to achieve.

    If you just want to display content defined in BaseObject.qml as instances in tour app just put
    @
    BaseObject{
    }
    @

    in your main.qml file (thus you don't need BaseObject.h and BaseObject.cpp).

    If you want to create instances of your BaseObject defined in C++ in your main.qml scene do the same but without creating a new viewer in your class creator
    @
    ui = new QDeclarativeView();
    @

    is what creates the new window in your code.

    Anyways in your current code's main.qml scope BaseObject is ambiguous as it may refer to the one defined in QML or the one defined in C++ (I don't know which one has priority here).

    Good luck!



  • I try to achieve ability of dynamic qml object's creation from C++ code. I need create some objects from C++ code and then show them as part of main.qml
    I tried to replace QDeclarativeView on

    @ QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine,
    QUrl::fromLocalFile("qml/PlanetWars/BaseObject.qml"));
    QObject *object = component.create();@

    but observe only RuntimeError.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.