在Qt 5中连接过载信号和插槽 [英] Connecting overloaded signals and slots in Qt 5

查看:1929
本文介绍了在Qt 5中连接过载信号和插槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在Qt 5中使用新的信号/插槽语法(使用指向成员函数的指针),如中所述新信号槽语法。我尝试改变这个:

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

到此:

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

但我在尝试编译时出现错误:


错误:没有匹配的函数调用 QObject :: connect(QSpinBox *&
<未解析的重载函数类型> QSlider *& void
(QAbstractSlider :: *)(int))


Linux,都有 -std = c ++ 11



我做错了什么,修复它?

解决方案


但我得到一个没有匹配的函数调用QObject :: connect

发出完成错误消息

时,错误



$ b 你从编译器得到的!编译器可能会抱怨传递给函数的错误参数(因此找不到正确的重载);或者在这种情况下,关于& QSpinBox :: valueChanged 是不明确的事实。




$ b $事实上,这里的问题是有两个这个名字的信号: QSpinBox :: valueChanged(int) QSpinBox :: valueChanged(QString)。你需要告诉Qt你想选哪一个,通过将它转换为正确的类型:

  connect(spinbox,static_cast  slider,& QSlider :: setValue); 

我知道,丑陋。但是没有办法解决这个问题。今天的课程是:不要超载您的信号和插槽!






/ strong>:真的很讨厌的演员是


  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 (您还有 qConstOverload qNonConstOverload ) 。



使用示例(来自文档):

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

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

//相同,与C ++ 11
QOverload<> ::(& Foo:overloadedFunction)
QOverload< int,QString& overloadedFunction)


I'm having trouble getting to grips with the new signal/slot syntax (using pointer to member function) in Qt 5, as described in New Signal Slot Syntax. I tried changing this:

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

to this:

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

but I get an error when I try to compile it:

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

I've tried with clang and gcc on Linux, both with -std=c++11.

What am I doing wrong, and how can I fix it?

解决方案

but I get a "no matching function for call to QObject::connect" error when I try to compile it

Please always post the complete error message you get from the compiler! The compiler might be complaining about wrong arguments passed to the function (so it doesn't find the right overload); or, in this case, about the fact that &QSpinBox::valueChanged is ambiguous.


In fact, the problem here is that there are two signals with that name: QSpinBox::valueChanged(int) and QSpinBox::valueChanged(QString). You need to tell Qt which one you want to pick, by casting it to the right type:

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

I know, it's ugly. But there's no way around this. Today's lesson is: do not overload your signals and slots!


Addendum: what's really annoying of the cast is that

  1. one repeats the class name twice
  2. one has to specify the return value even if it's usually void (for signals).

So I've found myself seldomly using this C++11 snippet:

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

Usage:

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

I personally find it not really useful. I expect this problem to go away by itself when Creator (or your IDE) will automatically insert the right cast when autocompleting the operation of taking the PMF. But in the meanwhile...

Note: the PMF-based connect syntax does not require C++11!


Addendum 2: in Qt 5.7 helper functions were added to mitigate this, modelled after my workaround above. The main helper is qOverload (you've also got qConstOverload and qNonConstOverload).

Usage example (from the docs):

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)

这篇关于在Qt 5中连接过载信号和插槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆