C++ 我什么时候应该使用Q_DECLARE_元类型?

C++ 我什么时候应该使用Q_DECLARE_元类型?,c++,qt,C++,Qt,文档说我需要Q_声明一个自定义结构的元类型,这样它就可以在信号槽中正常工作 但是我已经尝试了下面的代码,它似乎工作得很好 #include <QMainWindow> namespace Ui { class MainWindow; } struct MyStruct { int a; int b; }; class MainWindow : public QMainWindow { Q_OBJECT public: explic

文档说我需要Q_声明一个自定义结构的元类型,这样它就可以在信号槽中正常工作

但是我已经尝试了下面的代码,它似乎工作得很好

#include <QMainWindow>

namespace Ui {
class MainWindow;
}
struct MyStruct
{
        int a;
        int b;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

signals:
    void test(MyStruct);

public slots:
    void tested(MyStruct);
private slots:
    void on_pushButton_clicked();
};

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
//------------------------CPP-------------------------------
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(this, SIGNAL(test(MyStruct)),this,SLOT(tested(MyStruct)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::tested(MyStruct t)
{
    qDebug()<<t.a<<t.b;
}

void MainWindow::on_pushButton_clicked()
{
    MyStruct t;
    t.a=1;
    t.b=2;
    emit test(t);
}
看来我必须调用声明才能使用

声音类型::类型

在信号槽中


那么在什么情况下,我必须使用Q_DECLARE_元类型才能使用信号插槽呢?

它与信号和插槽没有任何关系<当您希望能够将自己的类型存储在
QVariant


请注意,此宏要求在使用该类型的位置完全定义该类型;对于指针类型,指针也必须完全定义,因此理想情况下,您应该将宏放在类声明之后(同样,只有当您想将类型对象存储在
QVariant
中时,才需要它)。

根据我的经验,要在Qt元对象系统中注册自定义枚举,您需要在其范围内使用
Q_enum
标记枚举,例如:

struct SoundType 
{
    enum Type
    {
        Bip = 0,
        LowBatt, 
        LowSat,
        FarAway,
        LostLink
    };
    Q_ENUM(Type);
};
例如,这将使我们能够在QML中使用enum(尽管父类型必须首先在QML中注册)。但是在许多情况下,包括在Qt本身(
qabstractemmodel::data(…,int role)
中),使用普通的
int
更方便

还有其他宏。通常,可以通过在结构开头键入
Q\u GADGET
来注册不是从
QObject
派生的自定义结构(就像
Q\u OBJECT
宏一样)。请注意,这种结构不能有信号或插槽,但它可以像往常一样使用
Q_属性
注册属性(尽管没有通知信号)

正如@singerofall所指出的,
Q\u DECLARE\u元类型将基于模板的类型注册到
QVariant
(因此可以使用
QVariant\u cast()检索它)

需要使用
qRegisterMetaType(name)
注册一些结构以在异步信号中排队,例如通过
QVector
的信号

我什么时候应该使用Q_DECLARE_元类型

当该类型与信号/插槽或
QVariant
一起使用时,始终使用该类型

您的测试用例是不完整的:只要您将一个连接的对象移动到另一个线程,它就会中断


您可能还需要
qRegisterMetatype()
例如,在
main
中,文档状态:。我很好奇,在文档中,您在哪里发现在信号/插槽中使用自定义结构时必须使用它?在这里:doc.qt.io/qt-4.8/custom-types.html,或者在Qt5中不再需要这样做了?或者它只是用于排队信号?在不使用
Q\u DECLARE\u元类型的直接信号插槽调用中使用自定义类型在我记忆中就一直有效。我不确定文档的这部分试图说明什么。@Nyaruko只需要排队连接,直接连接不需要在
QVariant
@Nyaruko中包装信号参数,如果在添加
Q\u DECLARE\u METATYPE
之前在信号和插槽上有任何错误,那么这只是巧合。在信号中使用枚举与使用类没有什么不同。
struct SoundType 
{
    enum Type
    {
        Bip = 0,
        LowBatt, 
        LowSat,
        FarAway,
        LostLink
    };
    Q_ENUM(Type);
};