我的模型是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中收到此信号?
答案 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中使用的接口,我发现了两种情况:
这是最简单的形式,而且你的方式正确。只需使用抽象方法和声明信号创建基于QObject的类。派生类不能再次声明信号,只需在需要时发出它们。
这是你的情况。 MOC生成器需要知道Base
接口有一个信号并且可以发出它。只需在Base
中声明信号而不是派生类。
有时您需要从任何基于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();
}