首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt:我什么时候使用Q_DECLARE_METATYPE?

Qt:我什么时候使用Q_DECLARE_METATYPE?
EN

Stack Overflow用户
提问于 2016-10-10 12:26:06
回答 3查看 2.2K关注 0票数 0

文档说,我需要Q_DECLARE_METATYPE一个自定义结构,这样它才能在信号槽中正常工作。

但是我已经尝试了下面的代码,它看起来很好吗?

代码语言:javascript
复制
#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);
}

信号插槽没有任何问题,但在以下情况下:

代码语言:javascript
复制
struct SoundType 
{
    enum Type
    {
        Bip = 0,
        LowBatt, 
        LowSat,
        FarAway,
        LostLink
    };
};
Q_DECLARE_METATYPE(SoundType::Type)

看来我必须调用声明才能使用

声音类型::类型

在信号槽里。

那么,在什么情况下,我必须使用Q_DECLARE_METATYPE才能使用信号插槽?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-10 12:27:30

它和信号和插槽没有任何关系。当您想要在Q_DECLARE_METATYPE中存储您自己的类型时,需要使用QVariant

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

票数 2
EN

Stack Overflow用户

发布于 2016-10-10 16:32:49

我什么时候使用Q_DECLARE_METATYPE?

当该类型与信号/插槽或QVariant. 一起使用时,总是

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

您还可能需要qRegisterMetatype<YourType>(),例如在main中。

票数 5
EN

Stack Overflow用户

发布于 2016-10-10 13:03:47

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

代码语言:javascript
复制
struct SoundType 
{
    enum Type
    {
        Bip = 0,
        LowBatt, 
        LowSat,
        FarAway,
        LostLink
    };
    Q_ENUM(Type);
};

例如,这将使我们能够在QML中使用枚举(尽管父类型必须首先在QML中注册)。但是,在许多情况下,包括Qt本身(例如QAbstractItemModel::data(..., int role)),使用普通int更方便。

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

正如@SingerOfTheFall所指出的,Q_DECLARE_METATYPE会将基于模板的类型注册到QVariant中(这样就可以使用qvariant_cast<T>()检索它)。

有些结构需要注册才能使用qRegisterMetaType<T>(name)在异步信号中排队,例如通过QVector<int>的信号。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39958267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档