如果参数不是从末尾开始,则说明您无法从 QT 信号槽连接中删除参数的文档在哪里?

Posted

技术标签:

【中文标题】如果参数不是从末尾开始,则说明您无法从 QT 信号槽连接中删除参数的文档在哪里?【英文标题】:Where is the documentation stating that you cannot remove a parameter from a QT Signal Slot connection if the parameter is not from the end? 【发布时间】:2017-07-18 14:38:44 【问题描述】:

在QT 4.8 documentation 中声明:

信号和槽机制是类型安全的:信号的签名必须与接收槽的签名匹配。 (事实上​​,一个槽的签名可能比它接收的信号更短,因为它可以忽略额外的参数。)由于签名是兼容的,编译器可以帮助我们检测类型不匹配。

然而代码如下:

QObject::connect(&source, SIGNAL(MySignal(QByteArray,QString,bool), &sink, SLOT(MySlot(QByteArray,bool));

给出“不兼容的发送方/接收方参数”错误。

为什么会发生这种情况?在哪里记录了您必须从末尾删除参数?我知道使用隐式转换可能会遇到麻烦,但我认为 QT 本质上是使用元数据,它应该能够像上面那样连接信号/插槽。

【问题讨论】:

有点无意义的问题,因为可以使用 Qt5 连接语法和 lambda 轻松完成。你只是使用了错误的连接方式。 【参考方案1】:

[...] 它可以忽略额外的参数。 [...]

除了显而易见的阅读方法之外,别无他法。 暂时承认这在技术上是可行的(相信我,这样做将是一场噩梦)并考虑以下陈述:

QObject::connect(
    &source,
    SIGNAL(MySignal(QString,QString,QString),
    &sink,
    SLOT(MySlot(QString,QString)
);

到目前为止,一切都很好。如果 Qt 像您描述的那样工作,那么要忽略的 QString 是什么? 您是否应该引入一套规则和例外来处理这些情况,以便它迅速将信号槽工具带入地狱?


话虽如此,从 C++11 开始,我们将 lambda 表达式作为语言的一部分。 Qt5 欢迎他们并定义了一组全新的connect 定义,您可以使用它们完全按照您的意愿行事。用手。当您真正需要它并且您知道自己在做什么时。这样框架就不能在发出事件时尝试猜测您的要求。

【讨论】:

谢谢,直到最近我们还没有使用 QT5 和 C++11。我在使用新的 QT5 连接调用方法(没有 Lambda)时仍然遇到问题,它抱怨对 staticMetaObject 的“未定义引用”。请注意,旧的基于 SIGNAL 和 SLOT 的连接可以在同一个地方正常工作。 @RobertDuff 可能您还没有从QObject 派生所有涉及的类型。不看真实代码,不好说。 该类是一个接口,但它是从 QObject 派生的(在基类声明中单独没有问题)并实现了 Q_OBJECT 宏。信号和析构函数不是纯虚的,但所有其他方法都是。不幸的是,我无法复制和粘贴代码,甚至无法编辑我正在使用的界面。 @RobertDuff 我不知道如何帮助你。你能创建一个最小的例子来重现错误吗?

以上是关于如果参数不是从末尾开始,则说明您无法从 QT 信号槽连接中删除参数的文档在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

信号和插槽的连接(关于 qlistview) - Qt

QT信号槽connect的第五个参数

Qt 浅析QFontMetrics 获取字体宽度,高度

Qt 浅析QFontMetrics 获取字体宽度,高度

Qt::浅谈信号槽连接,参数在多线程中的使用

Qt 槽函数怎么传递参数