Qt在网络上的信号/时隙机制
Qt's signal / slot mechanism over the network
我希望能够通过网络发送Qt信号。使用Qt的元类型系统,序列化信号调用是非常直接的
- 使用静态方法
::fromSignal
创建qMetaMethod
- 使用创建的元方法获取方法名称、参数名称、它们的typeId
[1]
和值 - 将所有内容打包成您喜欢的格式(JSON、XML)并发送
但到目前为止,我还不知道如何使用序列化数据调用信号:QMetaObject::invokeMethod(..)
将信号/方法名称作为字符串。问题是参数:它们必须以QGenericArgument
的形式提供,并且只能通过使用Q_ARG
宏来创建,该宏需要实际类型(而不是名称或typeId
的字符串)和相关值。此外,必须在编译时定义参数的数量,没有采用参数列表的invokeMethod(..)
。
我是不是错过了什么?或者有更好/替代的方法吗?
[1]
进一步的问题:当使用Q_DECLARE_METATYPE(..)
注册类型时,我如何确保它们总是获得相同的typeId?
不能自己创建QGenericArgument
是错误的。建议您不要这样做,但无论如何,您尝试做的事情都非常依赖于实现。它没有太多内容:您提供了一个类型名称和一个指向给定类型的数据的指针。例如:
QGenericArgument one() {
static const char type[] = "int";
static const int data = "1";
return QGenericArgument{type, (void*)&data);
}
有关更多示例代码,请参阅此答案的Introspectable Visitor部分。
如何确保类型在使用
Q_DECLARE_METATYPE(..)
注册时始终获得相同的typeId?
你没有。您应该使用类型名称,并且每个进程都应该在本地将这些名称解析为typeid。
除非你想自己实现它,否则使用现成的东西,比如麻省理工学院许可的qt远程信号。
你真的应该考虑使用Qt远程对象,因为它们可以完成你需要的一切,甚至更多(心跳、断开连接后自动重新连接、在引擎盖下使用QLocalSocket或QTcpSocket等)据我所知,它是最容易通过网络获取信号的方法。
https://doc.qt.io/qt-5/qtremoteobjects-index.html
您只需要定义.rep
文本文件,它就像IDL定义文件
class MyRemoteObject {
{
SIGNAL(foo(int value));
SIGNAL(bar(float value));
SLOT(somethingChanged(int newValue));
};
然后.rep
文件使用qmake或cmake调用的内置repc
编译器生成服务器端的代码(称为"源")和客户端的代码(也称为"副本")。"源"调用的每个信号都会自动发送到每个连接的"副本","副本"调用的插槽由"源"接收
- 理解boost::asio-async_read在无需读取内容时的行为
- 当回溯以零开始时,如何调试崩溃
- 为"adjacent"变量赋值时出现问题
- CMake-按正确顺序将项目与C运行时对象文件链接
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- Qt的新信号/时隙语法问题 - 连接到一个简单的函数
- QT信号和时隙将变量传递到另一种形式
- Qt时隙方法(这是另一类)在发射信号时不触发
- Qt:有没有什么方法可以调用具有一定时间间隔的时隙序列
- 当STL做得很清楚时,研究不同的排序算法机制的用途
- 通过信号和时隙系统调用类函数
- 使用新的 Qt5 信号/插槽机制连接 QTcpSocket::error() 时编译错误
- Qt:LNK2001和LNK2019 跨源文件实现信号/时隙后会出现错误
- 如何在运行时通过插件机制动态加载数据类型
- boost::信号2;没有用于添加信号时隙的匹配功能
- 实现编译时机制检查字符串的唯一性
- Qt5 信号/时隙语法,带过载信号和 lambda
- Qt在网络上的信号/时隙机制
- 当我从赋值操作符返回值时,首先,调用复制构造函数的机制和基础是什么?