【问题标题】:Wrapping connect method in Qt hides information needed by compiler在 Qt 中包装 connect 方法隐藏了编译器所需的信息
【发布时间】:2020-09-08 13:19:08
【问题描述】:

我想包装 Qt 连接方法(Qt5 语法),但无法编译我的代码。我能想到的最简单的例子是(未经测试,只是一般的想法):

// Called like this 
doConnect(&obj1,&obj1:sig,&obj2,&obj2::slot);

// Implemented here
void namespace::doConnect(
  const QObject* senderObject, 
  const QMetaMethod& senderSignal, {
  const QObject* receiverObject, 
  const QMetaMethod& receiverSlot) {
    connect(senderObject, senderSignal, receiverObject, receiverSlot);
}

当我尝试编译它时,我在调用 doConnect 的行上收到错误,

"没有匹配的函数调用 doConnect"

在连接线上

错误:静态断言失败:信号和槽参数不是 兼容的。

这听起来像信号和插槽有不同/不兼容的参数。但是,如果我通过将发送方对象/信号和接收方对象/插槽放在连接命令中直接调用连接,则它可以正常工作。所以这不是信号/插槽问题的特征。

这里有什么问题?将参数传递给函数是否首先隐藏了连接函数(或宏或模板)需要的一些信息?

【问题讨论】:

  • 很高兴看到实际调用和函数的确切签名作为信号和槽传递。

标签: c++ qt5 signals-slots qobject


【解决方案1】:

对我来说,以下效果很好:

void doConnect(const QObject* senderObject, const QMetaMethod& senderSignal, const QObject* receiverObject, const QMetaMethod& receiverSlot)
{
    QObject::connect(senderObject, senderSignal, receiverObject, receiverSlot);
}

您已经从编译器中编写了“信号和槽参数不兼容”。这并不奇怪。您可以尝试执行以下操作: QObject::connect(&obj1,&obj1:sig,&obj2,&obj2::slot);

你会得到同样的结果!您的函数签名不兼容。例如: QObject::connect(obj1, SIGNAL("remove(int)"), obj2, SLOT("handleRemove(QString)"); 只是通过这个连接,你会在运行时而不是在编译时得到错误。

它与以下内容相同: QObject::connect(obj1, &C1::remove, obj2, &C2::handleRemove);

你会得到同样的错误,因为是的,int 不是 QString。简单快速。参数的数量也是如此,如果有更多或更少,你可以通过它。

此外,创建一个与 QObject::connect 相同的函数 doConnect 是没有用的。阅读文档时要更加小心(如果您这样做了)。

【讨论】:

  • 问题指出,当使用相同的参数直接调用时,connect 工作正常。为什么使用中间函数会突然导致签名不兼容?您的回答没有解决这个问题 - 只是为签名兼容性提供了一个简单的解释。
猜你喜欢
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2017-02-05
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 2011-09-05
相关资源
最近更新 更多