我希望能够通过网络发送Qt信号。使用Qt的元类型系统序列化信号调用非常简单:
qMetaMethod
::fromSignal
[1]
和值。但到目前为止,我无法弄清楚如何使用序列化数据调用信号:QMetaObject::invokeMethod(..)
将信号/方法名称作为字符串。问题是参数:它们必须以QGenericArgument
提供,并且只能使用需要实际类型的Q_ARG
宏来创建它们(不是它的名称字符串或typeId
)和关注的价值。此外,必须在编译时定义参数的数量,没有invokeMethod(..)
来获取参数列表。
我错过了什么吗?或者有更好/替代方法来做到这一点?
[1]
进一步的问题:如何确保类型在使用Q_DECLARE_METATYPE(..)
注册时始终获得相同的typeId?
答案 0 :(得分:3)
您无法自己创建QGenericArgument
,这是错误的。你被告知不要这样做,但你要做的事情仍然是依赖于实现的。没有太多内容:您提供类型名称和指向给定类型数据的指针。 E.g:
QGenericArgument one() {
static const char type[] = "int";
static const int data = "1";
return QGenericArgument{type, (void*)&data);
}
有关更多示例代码,请参阅this answer的Introspectable Visitor部分。
如何确保类型在使用
Q_DECLARE_METATYPE(..)
注册时始终获得相同的typeId?
你没有。您应该使用类型名称,每个进程都应该在本地解析这些类型。
除非您想自己实施,否则请使用现成的东西,例如获得麻省理工学院许可的qt-remote-signals。
答案 1 :(得分:1)
您真的应该考虑使用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));
};
,然后使用内置的{{1},使用一个.rep
文件为服务器端生成代码(称为“源”),为客户端生成代码(称为“副本”)。 }由qmake或cmake调用的编译器。由“源”调用的每个信号都会在每个连接的“副本”之间自动发送,由“副本”调用的插槽将由“源”接收