Как передать 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));
Однако когда я это делаю, я получаю сообщение об ошибке замены и std::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));
Однако это также дает аналогичную ошибку при отсутствии преобразований. В этом нет никакого смысла, потому что теперь я использую указатель на функцию. Что, согласно документации по подключению, должно иметь возможность использовать указатель функции для их подключения. Так что либо я передаю его неправильно. Или то, чего я пытаюсь достичь, невозможно.
Любая помощь будет оценена по достоинству!
1 ответ
Посмотрев на комментарий GM, я понял, что они правы. АQObject*
это не 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)
};
Это будут закрытые члены любого класса, за который вы отвечаете. А затем в конструкторе вместо 6 строкconnect(object,SIGNAL,object,SLOT)
, вы можете затем поместить их в функцию и вызвать их следующим образом:
for(auto && tup : sliderConnections)
connect(std::get<0>(tup),std::get<1>(tup),this,std::get<2>(tup));
Это успешно соединяет все объекты с их соответствующими функциями. Опять же, это личные предпочтения. Мне просто было интересно, есть ли способ, и GM указал мне в правильном направлении.