Вызов метода Q_INVOKABLE в производном классе

У меня есть интересная проблема. Я не знаю, как объединить два класса, унаследованных от QObject. Базовый акцент на мою проблему с использованием метода Q_INVOKABLE в классе, производном от базового класса. Я хочу использовать «loadFromJson» несколько раз в разных «моделях».

Я уже пытался определить макрос Q_OBJECT и перестроить логику классов.

//model.h
class Model : public QObject{
   Q_OBJECT
public:
   Q_INVOKABLE bool loadFromJson(const QString &data);
}

//sqltablemodel.h
class SqlTableModel : public QSqlTableModel{
   //some code
}

//server.h
class Server : public SqlTableModel, Model
{
    Q_OBJECT
public:
    explicit Server(QString tableName = "");
};

//main.cpp
Server *server =  new Server();
    context->setContextProperty("server", server);
//

//server.qml
server.loadFromJson("123"); // not working


/*
If i remove QObject from Model then i can't call loadFromJson even Q_OBJECT defined, otherwise Server is ambigous using QObject. But i want to use methods from both base classes SqlTableModel & Model in derived Server with Q_INVOKABLE ability.
*/

main.cpp:41: ошибка: ‘QObject’ является неоднозначной основой ‘Server’ context->setContextProperty("server", server);

model.h:27: ошибка: неопределенная ссылка на `vtable for Model'


person exru    schedule 06.07.2019    source источник


Ответы (2)


Я бы использовал отношение «имеет» вместо «является». Это будет выглядеть примерно так:

class Server : public SqlTableModel {
  Q_OBJECT
  Q_PROPERTY(Model* model READ model WRITE setModel NOTIFY modelChanged)

  Model* _model;

 public:
  explicit Server(QObject* parent = nullptr)
      : SqlTableModel(parent), _model(new Model(this)) {}

 signals:
  void modelChanged(Model* model);

 public:
  Model* model() const noexcept { return _model; }
  void setModel(Model* m) noexcept { _model = m; }
};

Затем вы бы назвали это в своем qml следующим образом: server.model.loadFromJson("123");

Но также вы можете сделать так, чтобы Модель наследовала private QObject, если вы постараетесь решить проблемы, возникающие после этого.

person moisrex    schedule 06.07.2019
comment
Ой ну спасибо. Это хороший дизайн для моего опыта, но это не точная цель, которую я преследую. - person exru; 06.07.2019
comment
Затем вы можете использовать private QObject решение. Если вы наследуете от QObject в частном порядке, у moc не будет с этим проблем, насколько я знаю @exru - person moisrex; 06.07.2019
comment
В порядке. Я только что удалил SqlTableModel, но Q_INVOKABLE все еще не работает. - person exru; 06.07.2019
comment
какие ошибки при удалении? - person moisrex; 06.07.2019
comment
Build -> Runing -> loadFromJson не является функцией - person exru; 07.07.2019

Решил проблему с изменением порядка наследования. SqlTableModel->Модель->Сервер.

person exru    schedule 06.07.2019