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

2024-03-10

我使用 QT 5 和 WebChannel 与 HTML 页面进行通信。 我成功地能够传达文本和字符串。不过我想传达一些点数据。

官方文档说

“不需要手动消息传递和数据序列化,”http://doc.qt.io/qt-5/qwebchannel.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);

Per Qt 文档 http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1:

要在 QVariant 中使用类型 T,使用 Q_DECLARE_METATYPE() 是 充足的。要在排队信号和槽连接中使用类型 T, qRegisterMetaType() 必须在第一次连接之前调用 已确立的。

在我自己的代码中,我使用Q_DECLARE_METATYPE对于我想存储在的类QVariant(这个宏必须放在全局范围内)。和我qRegisterMetaType<T>()对于我想要传递给信号/槽的类(必须在建立 signal.slot 连接之前调用此函数)。如果只使用一项功能,我从来不需要同时调用这两个功能。

因此,对于您的示例,这应该有效:

qRegisterMetaType<MyData>( "MyData" );
// then, form here, you can connect `updateData(MyData)` signal to any slot taking a MyData parameter

对于信号/槽声明:

  • If qRegisterMetaType没有被调用,只能使用信号/槽传递MyData通过引用或指针(声明signal as void updateData(MyData& data); or void updateData(MyData* data);)。然后,如果进行异步连接,您必须非常小心(例如Qt::QueuedConnection)因为,作为slot将“稍后”执行,您必须保证对象引用保持有效,直到slot在你发出后被执行signal.
  • If qRegisterMetaType被调用时,您可以使用信号/槽传递MyData通过复制(声明signal as void updateData(MyData data);)。与通过副本传递的对象进行异步连接是安全的,因为 Qt 能够序列化对象(这意味着如果slot被“稍后”执行,最终会以全新的方式调用MyData从您发出信号的原始对象复制的对象,带有....而不qRegisterMetaType被调用时,Qt 无法执行此“复制”)。

确保MyData当您执行此操作时,声明是已知的(无前向声明)。

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

公共默认构造函数、公共复制构造函数和公共析构函数

你的情况就是这样MyData类(默认的就可以),所以它应该可以顺利工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何注册一个类以在 Qt 中的 QWebChannel 信号中使用它 的相关文章

随机推荐