2012-03-25 2 views
12

Для подключения сигналов к слотам, насколько мне известно, параметры сигнала должны соответствовать параметрам слота. Так, например:Подключите сигналы к слотам с постоянными значениями

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(closeDockWidget())); 

Но что, если я хочу, чтобы иметь сигнал вызова слот, который имеет различное количество параметров, но всегда проходят постоянное значение в слот. Например, используя вышеупомянутую часть кода:

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(setDockWidget(false))); 

Или, другими словами, всякий раз, когда нажимается кнопка, она вызывает функцию setDockWidget() с ложным параметром. Это возможно?

ответ

8

Нет, это невозможно. Вам разрешено подключать слоты с меньшим или равным количеством аргументов, чем в соответствующем сигнале. (см. documentation)

Вам необходимо создать прокси-слот, который будет называться желаемым.

+1

Этот ответ более недействителен, так как синтаксис Qt5 на C++ 11 позволяет легко использовать лямбда для этой цели. –

+1

@ André, С другой стороны, вы просто можете «создать прокси-слот, который будет называть нужный.» Теперь на месте – Lol4t0

+1

Конечно, вы можете. Но дополнительный слот означает, что в вашем заголовке больше нечего, выставляя внешние вызовы (да, даже если частный слот можно вызывать извне) и распространяется вокруг вашего кода в нескольких местах. Возможно, вам даже потребуются дополнительные переменные-члены для хранения значений, которые вы хотите передать, тем самым добавляя дополнительное состояние в свой класс. Решение лямбда настолько элегантнее, что дисквалифицирует введение прокси-слота в качестве решения IMO. –

6

В некотором смысле, да, вы можете. Но это не очень мощный: просто объявить setDockWidget таким образом:

[virtual] void setDockWidget(bool state=false) ; 

И объявите соединительном таким образом:

connect(emitter, SIGNAL(closeButtonClicked()), receiver, SLOT(setDockWidget())); 

setDockWidget вызывается без аргументов принимать те по умолчанию.

8

Вы можете использовать лямбда с желаемый звонок с постоянный аргумент. Пример:

connect(obj, &ObjType::signalName, [this]() { desiredCall(constantArgument); }); 

Подробнее о новом синтаксисе подключения: https://wiki.qt.io/New_Signal_Slot_Syntax.

+0

В вашем случае можно смешать постоянный аргумент с переменной? –

+0

@AlekseyKontsevich: Если я правильно вас понимаю, вы хотите передать переменную из сигнала в слот? Что вы можете. Сделайте это аргументом для лямбды и используйте этот аргумент в вызове функции. Тем не менее, я рекомендую использовать аргумент контекста со значением «this». Таким образом, вы можете быть уверены, что соединение будет разрушено, если объект-получатель будет уничтожен. В противном случае вы можете оказаться в неопределенном поведении. –

Смежные вопросы