c++ - 在 Qt 5 中连接重载的信号和插槽

标签 c++ qt qt5

我无法掌握 Qt 5 中新的信号/槽语法(使用指向成员函数的指针),如 New Signal Slot Syntax 中所述.我试着改变这个:

QObject::connect(spinBox, SIGNAL(valueChanged(int)),
                 slider, SLOT(setValue(int));

到这里:

QObject::connect(spinBox, &QSpinBox::valueChanged,
                 slider, &QSlider::setValue);

但是当我尝试编译它时出现错误:

error: no matching function for call to QObject::connect(QSpinBox*&, <unresolved overloaded function type>, QSlider*&, void (QAbstractSlider::*)(int))

我在 Linux 上尝试过使用 clang 和 gcc,两者都使用 -std=c++11 .

我做错了什么,我该如何解决?

最佳答案

这里的问题是有 两个 具有该名称的信号:QSpinBox::valueChanged(int)QSpinBox::valueChanged(QString)。从 Qt 5.7 开始,提供了帮助函数来选择所需的重载,因此您可以编写

connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
        slider, &QSlider::setValue);

对于 Qt 5.6 及更早版本,您需要通过将其转换为正确的类型来告诉 Qt 您要选择哪一个:

connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
        slider, &QSlider::setValue);

我知道,它。但是没有办法解决这个问题。今天的类(class)是:不要让你的信号和槽重载!


附录: Actor 阵容真正令人讨厌的是

  1. 一个类名重复两次
  2. 必须指定返回值,即使它通常是 void(用于信号)。

所以我发现自己有时会使用这个 C++11 片段:

template<typename... Args> struct SELECT { 
    template<typename C, typename R> 
    static constexpr auto OVERLOAD_OF( R (C::*pmf)(Args...) ) -> decltype(pmf) { 
        return pmf;
    } 
};

用法:

connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)

我个人觉得它不是很有用。我希望当 Creator(或您的 IDE)在自动完成获取 PMF 的操作时自动插入正确的类型转换时,这个问题会自行消失。但与此同时……

注意:基于 PMF 的连接语法不需要 C++11!


附录 2:在 Qt 5.7 中添加了帮助函数来缓解这种情况,模仿我上面的解决方法。主要助手是qOverload (您还有 qConstOverloadqNonConstOverload )。

使用示例(来自文档):

struct Foo {
    void overloadedFunction();
    void overloadedFunction(int, QString);
};

// requires C++14
qOverload<>(&Foo:overloadedFunction)
qOverload<int, QString>(&Foo:overloadedFunction)

// same, with C++11
QOverload<>::of(&Foo:overloadedFunction)
QOverload<int, QString>::of(&Foo:overloadedFunction)

附录 3:如果您查看任何重载信号的文档,现在文档本身已经清楚地说明了重载问题的解决方案。例如,https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1

Note: Signal valueChanged is overloaded in this class. To connect to this signal by using the function pointer syntax, Qt provides a convenient helper for obtaining the function pointer as shown in this example:

   connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });

关于c++ - 在 Qt 5 中连接重载的信号和插槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16794695/

相关文章:

c++ - std::vector::reserve 是否保证在这种情况下实现不会使迭代器无效?

c++ - Qt,在构造函数之外编辑小部件

c++ - 连接 Qt 应用程序中的 GUI 和计算

Qt 强制 QCheckBox 在 setChecked 上发出信号

python - CentOS:QtWebKit 丢失,Anki 无法启动

c++ - 如何识别 QWidget 上的点击类型

c++ - 如何在两个类之间连接函数

QToolButton 带图标 + 文本 : How to center both?

c++ - VirtualAlloc C++,注入(inject)的dll,asm

c++ - Boost.Coroutine 在 iPhone 上崩溃