【问题标题】:Passing structure to signal in Qt将结构传递给Qt中的信号
【发布时间】:2023-03-25 06:38:01
【问题描述】:

我想在 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 机器上发布这个。所以那个错误......我会编辑它......
  • 您知道,除非您使用排队连接,否则您不需要任何这些。 Read this 了解更多信息。
  • @Sid411 如果信号是从与对象的插槽所在的同一线程发出的,则它将是直接连接。在这种情况下,您不必使用 Q_DECLARE_METATYPE 声明自定义元类型。

标签: c++ qt qt-signals


【解决方案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@ 在我从 / 插槽检索发出的信号的班级中,它似乎运行良好,感谢发帖!
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 2019-09-19
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
相关资源
最近更新 更多