如何注册一个类以在Qt中的QWebChannel信号中使用它
How to register a class for use it in a QWebChannel signal in Qt
我使用带有WebChannel的QT 5与HTML页面进行通信。我成功地传达了文本和字符串。但是我喜欢传达一些积分数据。
官方文件说
"不需要手动传递消息和数据序列化," http://doc.qt.io/qt-5/qwebchannel.html
当我尝试发送对象或数组而不是字符串时,应用程序会抛出以下消息:
不知道如何处理"数据",请使用qRegisterMetaType来注册它。
如何使用 Point 类而不是字符串对象发出信号?或者将类序列化为字符串。
这是我想发送到我的 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);
每个Qt文档:
要在 QVariant 中使用类型 T,使用 Q_DECLARE_METATYPE() 是 足够。要在排队信号和插槽连接中使用类型 T, qRegisterMetaType() 必须在第一个连接之前调用 既定。
在我自己的代码中,我对要存储在QVariant
中的类使用 Q_DECLARE_METATYPE
(此宏必须放在全局范围内)。我qRegisterMetaType<T>()
对于我想传递给信号/插槽的类(必须在建立 signal.slot 连接之前调用此函数)。如果只使用一个功能,我永远不必同时调用这两个功能。
因此,对于您的示例,这应该有效:
qRegisterMetaType<MyData>( "MyData" );
// then, form here, you can connect `updateData(MyData)` signal to any slot taking a MyData parameter
对于信号/插槽声明:
- 如果未调用
qRegisterMetaType
,则只能通过引用或指针使用信号/插槽传递MyData
(将signal
声明为void updateData(MyData& data);
或void updateData(MyData* data);
)。然后,如果进行异步连接(如Qt::QueuedConnection
),则必须非常小心,因为由于slot
将在"稍后"执行,因此您必须保证对象引用保持有效,直到slot
在您发出signal
后被执行。 - 如果调用了
qRegisterMetaType
,则可以使用通过副本传递MyData
的信号/插槽(将signal
声明为void updateData(MyData data);
)。并且与那些通过复制传递的对象进行异步连接是安全的,因为Qt能够序列化对象(这意味着如果slot
"稍后"执行,它最终将被调用一个全新的MyData
对象从您发出信号的原始对象复制......如果不调用qRegisterMetaType
,Qt将无法执行此"复制")。
确保在执行此操作时已知MyData
声明(无前向声明)。
另请注意,并非所有类/结构都可以通过这种方式注册,它们必须具有:
公共默认构造函数、公共复制构造函数和公共析构函数
您的MyData
类就是这种情况(默认的没问题),因此它应该可以顺利运行。
你只需要在你的插槽之前的某个地方有一行,就像这样:
qRegisterMetaType<Block>();
您正在做的是告诉元对象编译器 (MOC) 有关您的类以及如何传递它的所有信息。进一步的阅读可以在这里找到,其中更详细地讨论了这个问题,并给出了例子。
您还需要将类型名称的字符串表示形式作为参数传递给函数
qRegisterMetaType<MyData>("MyData");
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- .cpp和.h文件中的模板专用化声明
- 反向给定链表中的K节点
- 正在查找文档以获得PS4平台的C++中的设备信息
- enum是C++中的宏变量还是整数变量
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 将字符串存储在c++中的稳定内存中
- 文本文件中的单词链表
- 递归函数计算序列中的平方和(并输出过程)
- 如何从C++中的依赖类型中获得它所依赖的类型
- C++中的"inline"关键字
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 用C++中的一个变量定义一个常量
- vector.resize()中的分配错误
- 使用指针从C++中的数组中获取最大值
- arr[-1]在c++中的奇怪行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 将值指定给向量(2D)的向量中的某个位置
- 如何注册一个类以在Qt中的QWebChannel信号中使用它