如何在QML中捕获从派生的c ++类发出的信号?

时间:2015-05-13 18:21:27

标签: qt qml

我的模型是C ++,前端是QML。该模型由一个包含其他组件的接口类组成。简化形式(概念证明阶段)此接口类是名为Base的纯虚拟类,派生自QObject。我有Derived来自Base

的类

当数据发生变化时,我在派生类中发出信号。我的问题是如何在QML中捕获这个信号和过程?

derived.obj:-1: error: LNK2019: unresolved external symbol "public: void __thiscall Derived::somethingChanged(void)" (?somethingChanged@Derived@@QAEXXZ) referenced in function "public: virtual void __thiscall Derived::doSomething(void)" (?doSomething@Derived@@UAEXXZ)

我的Base.h类是:

#include <QObject>

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

    virtual void doSomething() = 0;

signals:

public slots:
};

Derived.h是

#include "base.h"

class Derived : public Base
{
    Q_OBJECT
public:
    Derived();
    ~Derived();

    virtual void doSomething();

signals:
    void somethingChanged();
};

Derived.cpp是

#include "derived.h"

#include <QDebug>

Derived::Derived()
{

}

Derived::~Derived()
{

}

void Derived::doSomething()
{
    qDebug() << "doSomething() called in Derived";

    emit somethingChanged(); // this doesn't compile!
}


Connections {
    target: What? // what should I put here, 
    onSomethingChanged: console.log("The application data changed!")
}

问题是我还要为target属性添加什么?该模型仅将接口类暴露给qml,即Base类,但信号实际上是在派生类中发出的。信号是否也应该是虚拟的?我该如何在QML中收到此信号?

2 个答案:

答案 0 :(得分:1)

MOC是实现该功能的人(您的信号)void somethingChanged();

示例在moc_XYZ.cpp文件中可能如下所示。

// SIGNAL 13
void Derived::doSomething()
{
    QMetaObject::activate(this, &staticMetaObject, 13, Q_NULLPTR);
}

那么你如何让MOC高兴呢?

Q_OBJECT

中添加derived.h

答案 1 :(得分:0)

为了创建在Qt中使用的接口,我发现了两种情况:

  1. 基于QObject
  2. 这是最简单的形式,而且你的方式正确。只需使用抽象方法和声明信号创建基于QObject的类。派生类不能再次声明信号,只需在需要时发出它们。

    这是你的情况。 MOC生成器需要知道Base接口有一个信号并且可以发出它。只需在Base中声明信号而不是派生类。

    1. 纯虚拟课程(额外信息)
    2. 有时您需要从任何基于QObject的类派生(例如 QAbstractListModel ),但它也需要实现一些接口。 C ++允许多重继承,但Qt不喜欢从两个或多个基于QObject的类派生的类。 所以你应该创建一个 plain 纯虚拟类,并将信号声明为任何其他未实现的方法。

      // Base  
      class Base
      {
      public:
          Base();
          virtual ~Base(); 
      
          virtual void doSomething() = 0;
      
      signals:
          virtual void somethingChanged() = 0;
      
      };
      

      现在,从Base派生并再次声明信号:

      // Derived
      class Derived : public QObject, public Base
      {
          Q_OBJECT
      public:
          explicit Derived(QObject *parent = 0);
          ~Derived();
      
          //Implmetations of Base methods
      public:
          void doSomething();
      
          //Declaration of Base signals
      signals:
          void somethingChanged();
      
      }