Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何注册一个类以便在Qt中的QWebChannel信号中使用它_C++_Json_Qt_Communication_Qmetatype - Fatal编程技术网

C++ 如何注册一个类以便在Qt中的QWebChannel信号中使用它

C++ 如何注册一个类以便在Qt中的QWebChannel信号中使用它,c++,json,qt,communication,qmetatype,C++,Json,Qt,Communication,Qmetatype,Im使用Qt5和网络频道与HTML页面通信。 我能成功地传达文本和字符串。然而,我想传达一些观点和数据 官方文件说 不需要手动消息传递和数据序列化 当我尝试发送对象或数组而不是字符串时,应用程序会抛出以下消息: 不知道如何处理“数据”,请使用qRegisterMetaType注册它 如何使用Point类而不是string对象发出信号?或者将类序列化为字符串 这是我想发送到HTML的对象 点类 class MyData{ public : int x,y,z; }; Q_DECLARE_

Im使用Qt5和网络频道与HTML页面通信。 我能成功地传达文本和字符串。然而,我想传达一些观点和数据

官方文件说

不需要手动消息传递和数据序列化

当我尝试发送对象或数组而不是字符串时,应用程序会抛出以下消息:

不知道如何处理“数据”,请使用qRegisterMetaType注册它

如何使用Point类而不是string对象发出信号?或者将类序列化为字符串

这是我想发送到HTML的对象

点类

class MyData{
public :
    int x,y,z;
};
Q_DECLARE_METATYPE(MyData)
地图类

class MyMap : public QObject{
Q_OBJECT

public:
    explicit MyMap ();

signals:
    updateText(const QString &text); // registered
    updateData(MyData &data); //   Don't know how to handle 'data', use qRegisterMetaType to register it.

public slots:
    receiveText(const QString &text);
};
主代码是什么

qRegisterMetaType<MyData>();

// setup the channel
QWebChannel channel;
QObject::connect(&clientWrapper, &WebSocketClientWrapper::clientConnected, &channel, &QWebChannel::connectTo);

// setup the dialog and publish it to the QWebChannel
channel.registerObject(QStringLiteral("map"), &map);

map.updateText("text");

MyData data;
data.x=10;
data.y=12;
data.z=13;
map.updateData(data);
qRegisterMetaType();
//设置频道
QWebChannel频道;
QObject::connect(&clientWrapper,&WebSocketClientWrapper::clientConnected,&channel,&QWebChannel::connectTo);
//设置对话框并将其发布到QWebChannel
注册对象(QStringLiteral(“map”),&map);
map.updateText(“文本”);
MyData数据;
数据x=10;
数据y=12;
数据z=13;
地图更新数据(数据);

您只需在插槽前的某个位置画一行,如下所示:

qRegisterMetaType<Block>();
qRegisterMetaType();

您所做的是告诉元对象编译器(MOC)有关您的类的所有信息以及如何传递它。可以找到进一步的阅读资料,其中更详细地讨论了这个问题,并给出了示例。

您还需要将类型名称的字符串表示形式作为参数传递给函数

qRegisterMetaType<MyData>("MyData");
qRegisterMetaType(“MyData”);
根据:

要在QVariant中使用类型T,可以使用Q_DECLARE_METATYPE() 够了。要在排队信号和插槽连接中使用T类型, 必须在创建第一个连接之前调用qRegisterMetaType() 建立

在我自己的代码中,我对要存储在
QVariant
中的类使用
Q\u DECLARE\u元类型(这个宏必须放在全局范围内)。和I
qRegisterMetaType()
对于我希望传递给信号/插槽的类(必须在建立signal.slot连接之前调用此函数)。如果只使用一个功能,我就不必同时调用这两个功能

因此,就你的例子而言,这应该是可行的:

qRegisterMetaType<MyData>( "MyData" );
// then, form here, you can connect `updateData(MyData)` signal to any slot taking a MyData parameter
qRegisterMetaType(“MyData”);
//然后,从这里开始,您可以将`updateData(MyData)`信号连接到使用MyData参数的任何插槽
对于信号/插槽声明:

  • 如果未调用
    qRegisterMetaType
    ,则只能通过引用或指针使用信号/插槽传递
    MyData
    (将
    signal
    声明为
    void updateData(MyData&data);
    void updateData(MyData*data);
    )。然后,如果进行异步连接(如
    Qt::QueuedConnection
    ),您必须非常小心,因为
    插槽
    将“稍后”执行,因此必须保证对象引用在发出
    信号后执行
    插槽
    之前保持有效
  • 如果调用了
    qRegisterMetaType
    ,则可以通过复制使用信号/插槽传递
    MyData
    (将
    signal
    声明为
    void updateData(MyData数据);
    )。而且可以安全地与通过copy传递的对象进行异步连接,因为Qt能够序列化对象(这意味着如果
    插槽
    在“以后”执行)它最终将被调用一个全新的
    MyData
    对象,该对象是从您发出信号的原始对象复制而来的。……如果不调用
    qRegisterMetaType
    ,Qt将无法执行此“复制”)
执行此操作时,请确保知道
MyData
声明(无正向声明)

还请注意,并非所有类/结构都可以通过这种方式注册,它们必须具有:

公共默认构造函数、公共副本构造函数和公共析构函数


您的
MyData
类就是这种情况(默认的可以),因此它应该可以顺利工作。

添加我得到的这一行:\include\QtCore\qglobal.h:703:错误:“sizeof”对不完整类型“QStaticAssertFailure”枚举{Q_STATIC_ASSERT_PRIVATE_JOIN(Q_STATIC_ASSERT_result,COUNTER)=sizeof(QStaticAssertFailure)}^@DanielSantos MyData类不是一个QObject,它需要Q_DECLARE_元类型宏。我添加了这个(根据问题编辑),但是我得到了相同的输出(不知道如何处理“数据”,使用qRegisterMetaType来注册它。)通道发送一个“NULL”文本