C++ 如何注册一个类以便在Qt中的QWebChannel信号中使用它
Im使用Qt5和网络频道与HTML页面通信。 我能成功地传达文本和字符串。然而,我想传达一些观点和数据 官方文件说 不需要手动消息传递和数据序列化 当我尝试发送对象或数组而不是字符串时,应用程序会抛出以下消息: 不知道如何处理“数据”,请使用qRegisterMetaType注册它 如何使用Point类而不是string对象发出信号?或者将类序列化为字符串 这是我想发送到HTML的对象 点类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_
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元类型(这个宏必须放在全局范围内)。和IqRegisterMetaType()
对于我希望传递给信号/插槽的类(必须在建立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”文本