将结构传递给Qt中的信号

Posted

技术标签:

【中文标题】将结构传递给Qt中的信号【英文标题】:Passing structure to signal in Qt 【发布时间】:2013-10-16 07:31:43 【问题描述】:

我想在 Qt 中发送一个带有信号的结构。我怎样才能做到这一点?我知道如何用信号发送整数、字符串、图像等,但对结构部分感到困惑。我阅读了一些帖子并发现了有关 Q_DECLARE_METATYPE() 的信息,但我不明白如何使用它。

typedef struct

    int EmpId;
    QString Name; 
 StandardData; 

class Data::public QObject

    Q_DECLARE_METATYPE(StandardData);

    signals:
        void SignalData(const StandardData &f_objStandardCan);

我得到的错误 1.非命名空间范围类的显式专业化。 2.模板的特化必须出现在命名空间范围内 3. struct QMetaTypeId 用不同的访问重新声明。 谁能告诉我哪里出错了。

【问题讨论】:

您发布的代码无法编译。该结构有一个标识符,其中有一个空格。请发帖sscce。 我在 Linux 中工作并从 windows 机器上发布这个。所以那个错误......我会编辑它...... 试试qtcentre.org/archive/index.php/t-25868.html 您知道,除非您使用排队连接,否则您不需要任何这些。 Read this 了解更多信息。 @Sid411 如果信号是从与对象的插槽所在的同一线程发出的,则它将是直接连接。在这种情况下,您不必使用 Q_DECLARE_METATYPE 声明自定义元类型。 【参考方案1】:

错误是因为 Q_DECLARE_METATYPE 的使用在您的类声明中。它必须在任何类或命名空间之外。你只需要像这样移动它:

typedef struct

  int EmpId;
  QString Name; 
 StandardData;

Q_DECLARE_METATYPE(StandardData);

【讨论】:

你不需要;之后的Q_DECLARE_METATYPE(StandardData) 只是没看到;并在课堂上打电话。但是,这难道不是 typedef 的隐含特化吗?【参考方案2】:

正如你已经发现的那样,你必须使用Q_DECLARE_METATYPE 来让 Qt 知道该类型。

struct StandardData 
    int EmpId;
    QString Name;
; Q_DECLARE_METATYPE(StandardData)

此外,您可能需要致电qRegisterMetaType。具体来说,必须在使用队列信号/插槽连接中的结构之前或在将其与QObject::property() API 一起使用之前调用该函数。

qRegisterMetaType<StandardData>();

工作示例

标准数据.h

struct StandardData 
    int EmpId;
    QString Name;
; Q_DECLARE_METATYPE(StandardData)

main.cpp

int main(int argc, char *argv[])

    // Register types on startup
    qRegisterMetaType<StandardData>();

    // Continue with the program
    // ...

静态初始化技巧

有一个技巧可以用来调用qRegisterMetaType,而无需修改任何不相关的文件(如main.cpp)。这个技巧使用静态初始化。但是,我没有找到任何说明支持此功能的 Qt 文档。此外,在动态库中使用时,这可能会导致问题。

标准数据.h

// The header file looks the same as above
struct StandardData 
    int EmpId;
    QString Name;
; Q_DECLARE_METATYPE(StandardData)

标准数据.cpp

// We don't need this global variable at all. We just want to ensure that
// qRegisterMetaType is called when the application starts.
static const int typeId = qRegisterMetaType<StandardData>();

Q_GADGET

或者,您可以使用Q_GADGET 代替Q_DECLARE_METATYPE

class StandardData 
    Q_GADGET
public:
    int EmpId;
    QString Name;
;

// You still have to call qRegisterMetaType if used for queued signals or
// as property.
qRegisterMetaType<StandardData>();

【讨论】:

我有一个通过信号和插槽发送的结构。信号被发出,但插槽从未被触发(奇怪的是,我浏览了代码,在哪里调用了 QObject::activate()**argv0x0。我在 struct 声明和 @ 之后添加了 Q_DECLARE_METATYPE 987654345@ 在我从 / 插槽检索发出的信号的班级中,它似乎运行良好,感谢发帖!

以上是关于将结构传递给Qt中的信号的主要内容,如果未能解决你的问题,请参考以下文章

Qt:将指针传递给 QMimeData 中的 QObject

Qt 信号槽传递自定义结构体

通过 Qt 信号/槽跨线程传递对象

QT中的信号与事件,多线程

在Qt中通过信号和插槽系统传递变量[关闭]

QT多线程问题:子线程中的变量如何传递给主线程?