首页 > 解决方案 > 如何将 std::function 或函数指针传递给 qtconnect?

问题描述

这主要是为了清理我的构造函数中的一堆代码。仅在构造函数中我就有大约 20 多行,connect(object, func1, this, func2)我正在尝试通过使用std::vector<std::tuple<QObject*,std::function<void()>,std::function<void>>>> connections;

如果我能做这样的事情,效果会很好:

std::vector<std::tuple<QObject*,std::function<void()>,std::function<void>>>> connections = {
  std::make_tuple(mySlider, std::bind(&QSlider::sliderReleased,mySlider, std::bind(&Foo::onSliderChanged,this)),
  .
  .
  .
};

然后这样称呼它:

for(auto &&e : connections)
  connect(std::get<0>(e),std::get<1>(e),this,std::get<2>(e));

但是,当我这样做时,我收到一个错误,即存在替换失败并且 astd::function<void()>无法转换为函数指针。所以决定改变它并创建实际的函数指针,如下所示:

typename void(Foo::*fooFunc)();
typename void(QSlider::*sliderFunc)();

std::vector<std::tuple<QObject*,sliderFunc,fooFunc>> sliderConnections = {
  std::make_tuple(mySlider, &QSlider::sliderReleased, &Foo::onSliderChanged),
  .
  .
  .
};

同样的事情,然后我尝试调用它:

for(auto &&e : sliderConnections)
  connect(std::get<0>(e),std::get<1>(e),this,std::get<2>(e));

但是,这也会在没有转换的情况下提供类似的错误。这没有任何意义,因为现在我实际上正在使用函数指针。根据连接文档,它应该能够使用函数指针来连接它们。所以要么我错误地传递它。或者我想要达到的目标是不可能的。

任何帮助,将不胜感激!

标签: c++qtfunction-pointersqt-connection

解决方案


看了 GM 的评论后,我意识到他们是正确的。AQObject*不是 a QSlider*,因此当尝试调用该函数QSlider::sliderReleased时,它无法连接两者,因为QObject没有滑块。因此,一旦我在元组向量中更改了它,编译的代码就很好了。

前任:

typedef void(Foo::*fooFunc)();
typedef void(QSlider::*sliderFunc)();
typedef void(QSpinBox::*spinFunc)();

const std::vector<std::tuple<QSlider*, sliderFunc, fooFunc>> sliderConnections = {
  std::make_tuple(slider1, &QSlider::sliderReleased, &Foo::onSlider1Changed),
  std::make_tuple(slider2, &QSlider::sliderReleased, &Foo::onSlider2Changed),
  std::make_tuple(slider3, &QSlider::sliderReleased, &Foo::onSlider3Changed)
};

const std::vector<std::tuple<QSpinBox*, spinFunc, fooFunc>> spinConnections = {
  std::make_tuple(spin1, &QSpinBox::editingFinished, &Foo::onSpin1Changed),
  std::make_tuple(spin2, &QSpinBox::editingFinished, &Foo::onSpin2Changed),
  std::make_tuple(spin3, &QSpinBox::editingFinished, &Foo::onSpin3Changed)
};

这些将是您负责的任何班级的私人成员。然后在构造函数中connect(object,SIGNAL,object,SLOT),您可以将它们放入一个函数中,而不是 6 行,然后像这样调用它们:

for(auto && tup : sliderConnections)
  connect(std::get<0>(tup),std::get<1>(tup),this,std::get<2>(tup));

这成功地将所有对象连接到其适当的功能。再次,这是个人喜好。我只是想知道是否有办法,通用汽车为我指出了正确的方向。


推荐阅读