4

我想在 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);
}

我在非命名空间范围类中得到 re 1.explicit specialization 的错误。2.模板的特殊化必须出现在命名空间范围 3. struct QMetaTypeId 用不同的访问重新声明。有人可以告诉我哪里出错了。

4

2 回答 2

10

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

typedef struct
{
  int EmpId;
  QString Name; 
} StandardData;

Q_DECLARE_METATYPE(StandardData);
于 2013-10-16T08:39:06.633 回答
3

正如您已经发现的那样,您必须使用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)

主文件

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>();
于 2017-06-25T20:51:36.857 回答