2
votes

I need to have "myclient" class that handles input data from socket. After data arrives it should call function "add" from qml model class "mymodel". How can I access the instance of the model that is created in main.cpp?

Here is an example which has text entering functions:

Classes: main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "mymodel.h"
#include "myclient.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    MyModel *theModel=new MyModel;
    engine.rootContext()->setContextProperty("theModel", theModel);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    myclient cli;    //doesn't add the data to list in it's constructor
    theModel.add("Added in main.cpp");   //works as expected

    return app.exec();
}

Now here is class myModel.h

#ifndef MYMODEL_H
#define MYMODEL_H
#include <QObject>
#include <QAbstractTableModel>
#include <QModelIndex>
#include <QHash>
#include <QVariant>
#include <QByteArray>
#include <QList>
#include <QDebug>


class MyModel: public QAbstractListModel
{
    Q_OBJECT
public:
    MyModel(QObject* parent=nullptr): QAbstractListModel (parent)
    {
        innerModel.append("Bob");
        innerModel.append("Patrick");
        innerModel.append("Alice");
    }
    Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override
    {
        if (parent.isValid())
            return 0;
        return innerModel.size();
    }
    Q_INVOKABLE int columnCount(const QModelIndex &parent = QModelIndex()) const override
    {
        if (parent.isValid())
            return 0;
        return 2;
    }
    Q_INVOKABLE QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
    {
        qDebug() << index << role;
        switch (role)
        {
            case Qt::DisplayRole:
            case Qt::UserRole + 1:
                return innerModel.at(index.row());
            case Qt::UserRole + 2:
                return QString::number(index.row() + 1);
        }
        return QVariant();
    }

    Q_INVOKABLE QHash<int,QByteArray> roleNames() const override
    {
        QHash<int,QByteArray> roles;
        roles.insert(Qt::UserRole + 1, "name");
        roles.insert(Qt::UserRole + 2, "index");
        return roles;
    }

    Q_INVOKABLE void add(QString const& name)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        innerModel.append(name);
        endInsertRows();
    }
    private:
        QList<QString> innerModel;
};
#endif // MYMODEL_H

and finally myclient.h

I tried this way but i'm aware that i'm creating another instance of myModel here

#ifndef MYCLIENT_H
#define MYCLIENT_H
#include "mymodel.h"

class myclient
{
public:
    myclient()
    {
        MyModel mod;
        mod.add("Added from myclient");
    }
};

#endif // MYCLIENT_H

How can I access methods of myModel (instance that is loaded into engine in main.cpp) in other parts of the app? Or is there another way of doing this? Thanks

1

1 Answers

1
votes

If you want to access the model in the client class then pass it as the argument of the constructor to be a member of the class.

myclient.h

#ifndef MYCLIENT_H
#define MYCLIENT_H
#include "mymodel.h"

class myclient
{
public:
    myclient(MyModel *model): m_model(model)
    {
        m_model->add("Added from myclient");
    }
private:
    MyModel *m_model;
};

#endif // MYCLIENT_H

main.cpp

// ...
myclient cli(&theModel);
// ...