Handling with pages in qml

332 views Asked by At

I've just begun to learn Qml.Altought i read too many qt tutorial, still struggling with some problems. I want to make multipages desktop application using OpenGL. First of all, in main function of the program, i am transmitting class instance so that i could access them in qml by using below code snippet.

QQmlApplicationEngine engine;
Foo foo;
engine.rooContext()->setContextProperty(QStringLiteral("foo"),&foo);

But if i must instance all of classes that i want to use in qml, it means there will be a hundred of instances in main function. I think there must be more proper way to do it.

Secondly, if we register object by using qmlRegisterType and import in qml file, can i reach property of bar class after active qml changed ? Because as far as i know, object of bar class is created when corresponding qml is loaded.

Project.cpp

    int main(int argc, char **argv)
{  
    
    QGuiApplication app(argc, argv);

    qmlRegisterType<bar>("MyLib", 1, 0, "Comp");
    qmlRegisterType<bar2>("MyLib2", 1, 0, "Comp2");


    QQmlApplicationEngine engine;
    Foo foo;
    engine.rooContext()->setContextProperty(QStringLiteral("foo"),&foo);
    .
    .
    .
}

GlWindow.qml

    import QtQuick 2.0
    import MyLib 1.0

   Comp
   {
    id:sample
   }

GlWindow2.qml

    import QtQuick 2.0
    import MyLib2 1.0

   Comp2
   {
    id:sample2
   }

bar.h

class bar: public QObject
{
    Q_OBJECT

public:
    Product* product;
    void initialize();//Initialize Gl
    void render();  //paint product's context 
}    

bar2.h

class bar2: public QObject
{
    Q_OBJECT

public:
    Product* product2;
    void initialize();//Initialize Gl
    void render();  //paint product's context 
}

I painted content of product on GlWindow.qml after that closed this qml and showed GlWindow2.qml. My problem starts here, how to transmit content of product to product2?

1

There are 1 answers

0
Amfasis On

For your first concern you can create a "main model" with properties for each of your models you would otherwise have added to the rootContext:

Class MainModel : public QObject
{
    Q_OBJECT

    Q_PROPERTY(Foo1 *foo1 READ foo1 CONSTANT)
    Q_PROPERTY(Foo2 *foo2 READ foo2 CONSTANT)
    ....
    Q_PROPERTY(FooN *fooN READ fooN CONSTANT)
}

If you fancy some design patterns, you can also go the kinda dependency injection rout:

Class Injector : public QObject
{

  public:
   Q_INVOKABLE QObject* getFoo(const QString& fooName);
}

This has the downside of losing the strong typed return value, but on the plus side you can use caching etc.


About your second question: you are correct, programming it like that it's hard to gain access from the C++ side (assuming that's what you mean) unless you make it a singleton:

class bar : public QObject
{
  public:
    bar *instance() 
    {
       static bar theInstance;
       return &theInstance;
    }
};

//main.cpp
qmlRegisterSingleton<bar>("MyLib", 1, 0, "Comp", [](QQmlEngine *eng, QJSEngine *js) -> QObject* 
{ 
    return bar::instance(); 
});

But you probably tried that route because you didn't see the "main model" idea.

Also your last question about passing information between models can likely be easily solved by having a nice "main model" where classes know about each other, or can signal and the "main model" connects the signals and slots.