Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Setting a C++ Object as a Context Property outside of Main.cpp



  • I have gone through numerous tutorials and Qt source examples regarding binding QML and C++ and it seems that just about every resource I have seen uses a custom QObject based class and either a context property driven from the perspective of creating either a QQuickView or deriving the QQmlContext from the QQmlEngine, instantiating an instance of your class, calling "rootContext()->setContextProperty()" with the associated value and name arguments and finally calling "setSource()" to associate the view object w/the relevant QML source OR by way of qmlRegisterType.

    That seems ok for a very basic UI but what about if I wanted a more complex view like several ListView elements which are contained in one .qml file? I wouldn't think I should have to instantiate EVERY one of my classes which are used w/either setContextProperty or qmlRegisterType in the main.cpp file? I want to mimic the workflow I have done using QWidgets in the past. In other words, with QWidgets, for a given view, I would create a .ui, .h and .cpp file. In the .cpp file, I can directly access a QListWidget component and populate it with values from a QList which I instantiate and populate in the same .cpp implementation file. Or another example would be that I could have a QTableView QWidget which is eventually populated based on an implementation of a QAbstractItemModel(let's say we are using a QSqlQueryModel) which is populated in a lower level Data Accessor Layer function that instantiates the QSqlQueryModel object which is populated based on queried db data and then this QSqlQueryModel object is passed up through the layers of abstraction to eventually be loaded into the QTableView by way of QTableView::setModel();

    In other words, is QML designed in a way where ALL QObject based user objects which I create for use in a single view/.qml file need to be instantiated in the main.cpp or .qml file itself in order to be bound to the view through either qmlRegisterType or setContextProperty? If so, then it seems like you would want to create quite an extensive hierarchy of smaller .qml files which would be embedded together based on very small footprint implementations or isolated areas of functionality. For example, an embedded .qml file inside a master or parent .qml file for every group of UI rendering which you wanted to accomplish.

    I hope this makes sense. It doesn't seem like what I am trying to do is to over the top or advanced. It's actually very simple but perhaps it's just that I don't understand the basic design premise of QML.

    Any help is greatly appreciated! Thanks!





  • Thank you for the recommendation. I have glanced at this link before but have not really seen any helpful pointers to solve the problem of instantiating, say, a model class(let's say we are using a QSqlQueryModel in this case) from one of my lower level C++ classes and then tying it to the QML view. Unless the Qt docs are proposing that what's described at this link: https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#exposing-c-data-models-to-qml
    is the only way to accomplish what I am trying to do? If registering my C++ extended QSqlQueryModel class as a QML plugin would solve this problem, I am fine with doing that but I still don't quite understand how my lower level C++ classes are going to be able to access and populate the data in that model class.

    I have read through many of the links which are accessible through the link which you shared and have come across many confusing statements, such as: Registering an Instantiable Object Type
    Any QObject-derived C++ class can be registered as the definition of a QML object type. Once a class is registered with the QML type system, the class can be declared and instantiated like any other object type from QML code. Once created, a class instance can be manipulated from QML; as Exposing Attributes of C++ Types to QML explains, the properties, methods and signals of any QObject-derived class are accessible from QML code.
    That's all well and good, but I don't want to manipulate class from QML. I want to manipulate it from my C++ code.

    Again, basically I want to populate a model class w/data queried from a database several abstraction layers deep in my object hierarchy. I then want that model data to be able to be bound to a ListView in a QML document. This seems like something which would be extremely common and I am at a loss as to why it is so hard to construct? I suppose I am just still not understanding the premise of QML/C++ interaction.



  • I mean I don't quite understand where the difficulty would lie in what you seem to want to accomplish. For example, you can simply create a C++ class derived from QObject, then use Q_PROPERTY and Q_INVOKABLE functions to make C++ models, objects and functions exposed to QML. You can implement the "deep logic" that you are talking about in that class, Then you can expose your derived class to qml as a context property.



  • @daljit97 The main problem I have a difficult time grasping is if I want to create a model to associate to a view and I want to create that model several abstraction layers below the C++ function which originally gets triggered in the view, I then have to pass that model all the way back up to the view in order to use it in a "setContextProperty" or "qmlRegisterType" call.

    The other way to do it would be to simply have a one-to-one relationship between the view and model, create the view inside the model class and use signals and slots to communicate between the two. I was hoping to take advantage of some of the benefits of QPROPERTY however.


Log in to reply