Qt中自定义结构体、枚举型做信号参数传递

参考链接

  1. 如何在QT信号和插槽中使用枚举
  2. Qt出现QObject::connect: Cannot queue arguments of type '******'的解决方法;

问题

当自定义结构体、枚举通过信号的参数进行传递的时候,运行以后可能会报错“QObject::connect: Cannot queue arguments of type 'XXX'”,此时信号与槽不一定会生效,但是编译过程是没问题的。因此,这样的问题比较麻烦,应该尽力规避。

解决

出现这样的问题是由于自定义的结构体、枚举,没有注册进qt的元对象系统,因此无法识别。
在声明结构体和枚举后应使用Q_ENUM()宏进行注册,再用qRegisterMetaType("XXX");进行注册。

示例

Communication.h如下:

class Communication : public QObject
{
    Q_OBJECT
public:
    enum COMMUNICATION_METHOD
    {
        TCP_CONNECT = 0,
        UDP_CONNECT,
        COM_CONNECT
    };

    enum CONNECT_TYPE {
        LONG_CONNECTION = 0,
        SHORT_TCONNECTION
    };

    Q_ENUM(COMMUNICATION_METHOD)
    Q_ENUM(CONNECT_TYPE)

    explicit Communication(QObject *parent = NULL);
    ~Communication();
}

Communication.cpp如下:

Communication::Communication(QObject *parent) : QObject(parent)
{
    qRegisterMetaType<Communication::CONNECT_TYPE>("Communication::CONNECTTYPE");
    qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
}

补充

为什么不使用Q_ENUMS()

关于Q_ENUMS(),Qt5.14.2的Qt助手是这样描述的:

This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.
This macro registers one or several enum types to the meta-object system.
If you want to register an enum that is declared in another class, the enum must be fully qualified with the name of the class defining it. In addition, the class defining the enum has to inherit QObject as well as declare the enum using Q_ENUMS().
In new code, you should prefer the use of the Q_ENUM() macro, which makes the type available also to the meta type system. For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS().

大意可翻译为:

此功能已过时。 提供它是为了使旧的源代码正常工作。 我们强烈建议不要在新代码中使用它。
此宏将一种或几种枚举类型注册到元对象系统。
如果要注册在另一个类中声明的枚举,则该枚举必须使用定义它的类的名称完全限定。 另外,定义枚举的类必须继承QObject并使用Q_ENUMS()声明枚举。
在新代码中,您应该更喜欢使用Q_ENUM()宏,这会使该类型也可用于元类型系统。 例如,QMetaEnum :: fromType()不适用于用Q_ENUMS()声明的类型。

你可能感兴趣的:(Qt,qt,自定义结构体,自定义枚举)