Russian Qt Forum
Ноябрь 26, 2024, 00:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: lambda функция слота clicked  (Прочитано 14501 раз)
Nuclears
Гость
« : Июль 06, 2013, 21:47 »

Итак, с совсем недавнего времени перешел на Qt, с++ не знаю совсем, вообщем очередное пополнение среди быдлокодеров Улыбающийся
Перейдем к делу.

просто и элегантно это сделать в python:
Код:
self.Button.clicked.connect(lambda : self.SomeFunc(param))


Что же в Qt(с++):
Код:
//изврат же!
QObject::connect(ui->Button, &QPushButton::clicked, [=] (bool clicked) {
        if (!clicked) {
            this->SomeFunc(param);
        }
    });

Существует ли более изящный способ?
Нечто такое, которое естественно не работает, т.к. нет параметров у сигнала.
Код:
QObject::connect(this->ui->Button, SIGNAL(clicked()), this, SLOT(this->SomeFunc(param)));

ЗЫЖ Сигналмаппер опять же разрастание кода.

ЗЫЫЖ Кто не знает о lambda рекомендую:
http://woboq.com/blog/cpp11-in-qt5.html
Ну и Qt5 идет почти в ногу со временем Улыбающийся
https://qt-project.org/wiki/New_Signal_Slot_Syntax


NB: Вопрос состоит в том, как просто и элегантно передать в слот параметры, при сигнале не имеющего параметров, а не в  "идеологии" этого процесса. Почитайте информацию по ссылкам, все встанет на свои места.
« Последнее редактирование: Июль 07, 2013, 16:47 от Nuclears » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Июль 07, 2013, 01:09 »

Си++ это Си++
Пиши в его стиле. Сделай слот (функцию-член класса),  к нему и цепляйся.
Записан

Юра.
Nuclears
Гость
« Ответ #2 : Июль 07, 2013, 09:20 »

Си++ это Си++
Пиши в его стиле. Сделай слот (функцию-член класса),  к нему и цепляйся.
Он такой же суровый как питон, не воспринимающий табуляцию Улыбающийся
Неужели на каждое действие(однотипное с переменной) необходим свой слот? Конструкция с лямбдой у мну работает, но  вопрос в ее "изяществе" и поведении в исключительных ситуациях.
Да и новый тип сигнал/слот в qt5 тонко намекает, что использование лямбд упрощает жизнь и код Улыбающийся
« Последнее редактирование: Июль 07, 2013, 09:24 от Nuclears » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Июль 07, 2013, 14:07 »

>>новый тип сигнал/слот в qt5 тонко намекает, что использование лямбд упрощает жизнь и код
не согласен.
Приведённый тобою код на Си++ (нового стандарту) ниразу не понятен. Что там за проверка на "Не щёлкнули"? с чего тогда сигнал был послан?

>>Неужели на каждое действие(однотипное с переменной) необходим свой слот
На каждое событие (сигнал), а не на каждое действие.
Слот может быть и один, и в нём можно многое разруливать.

А вообще стоит подумать над имеющейся архитектурой, нужна ли функция SomeFunc вообще? Может лучше сделать подходящий слот?
Записан

Юра.
Nuclears
Гость
« Ответ #4 : Июль 07, 2013, 15:40 »

>>Приведённый тобою код на Си++ (нового стандарту) ниразу не понятен. Что там за проверка на "Не щёлкнули"? с чего тогда  cигнал был послан?
Мой код лямбды не нового стандарта. bool clicked можно заменить на bool matumba, это просто лябда, и никакого отношения к сигналу не имеет.
Новый стандарт мну упомянул для примера, в котором нет функционала, когда сигнал не имеет параметров, а передать в слот нужно какой-то параметр.

>>На каждое событие (сигнал), а не на каждое действие.
>>Слот может быть и один, и в нём можно многое разруливать.
Именно это и пытаюсь сделать, создав один слот, в который можно передать параметр. А передать параметр можно только тогда, когда у сигнала он есть. Посмотри код внимательно, испытай код, сразу станет понятно.

>>А вообще стоит подумать над имеющейся архитектурой, нужна ли функция SomeFunc вообще? Может лучше сделать подходящий слот?
SomeFunc - это ни что иное как слот, по коду этого не видно?
Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды.
« Последнее редактирование: Июль 07, 2013, 15:47 от Nuclears » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Июль 07, 2013, 16:11 »

Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды.

Идеология сигнально-слотового механизма (когда его придумывали) подразумевает, касательно описанного случая, следующее:
Когда кнопку "нажали", то ей вообще фиолетово, кто подписан на её сигнал "меня нажали".

Если логика вашего подхода требует по мимо этого, какие то дополнительные связи между сендером и рецийвером, то скорее всего - это  следствие похоспроектированной архитектуры.. То, о чём говорил lit-uriy

Потом, при объявлении лямды, она должна знать о вашем "param", что уже накладывает связь между сендером и получателем.. Что, в свою очередь, противоречить концепции сигнально-слотового механизма..

В идеале, ни тот, кто посылает сигнал, ни тот, кто его принимает, ничего не должен знать друг о друге. 

 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #6 : Июль 07, 2013, 16:13 »

Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды.
упомянутый уже QSignalMapper; setObjectName() на крайний случай. С++ это не пайтон, смирись.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Nuclears
Гость
« Ответ #7 : Июль 07, 2013, 16:27 »

Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды.
упомянутый уже QSignalMapper; setObjectName() на крайний случай. С++ это не пайтон, смирись.
Прекрасно понимаю, что это классика C++, тем не менее лямбда из моего кода тоже функциональна.
Но кроме этих возможностей, может еще есть какие либо решения данной задачи? Неужели все дружно используют QSignalMapper? Улыбающийся
Плодить код ради кода, меня такой подход в c++ настораживает Улыбающийся
Записан
Nuclears
Гость
« Ответ #8 : Июль 07, 2013, 16:39 »

Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды.

Идеология сигнально-слотового механизма (когда его придумывали) подразумевает, касательно описанного случая, следующее:
Когда кнопку "нажали", то ей вообще фиолетово, кто подписан на её сигнал "меня нажали".

Если логика вашего подхода требует по мимо этого, какие то дополнительные связи между сендером и рецийвером, то скорее всего - это  следствие похоспроектированной архитектуры.. То, о чём говорил lit-uriy

Потом, при объявлении лямды, она должна знать о вашем "param", что уже накладывает связь между сендером и получателем.. Что, в свою очередь, противоречить концепции сигнально-слотового механизма..

В идеале, ни тот, кто посылает сигнал, ни тот, кто его принимает, ничего не должен знать друг о друге. 
 
Это и ежу понятно, что пофиг кто, есть факт создания сигнала.
Почему же сразу говорим "это  следствие похоспроектированной архитектуры" новому былдокодеру? Улыбающийся
Представь таблицу в которой толпа строк, допустим 3 столбца, первый некое значение, второй некое значение, третий кнопка, при нажатии которой некое значение передаётся в слот, что-то исполнятся и таблица полностью перестраивается.
Классикой - сигнал маппер, отлавливаем и передаем в слот, принимающий уже от сигналмаппера значение.
Либо создать столько же слоток как и кнопок -> это уже, конечно, суицидальный метод.
Лямбдой же прямо в слот передаем значение, делаем что-то. В этом случаем мы пропускаем ненужный фильтр. Утрировано - экономим процессорное время.

При динамеском создании param берется опять же как и все остальные данные, из источника создания динамики. Это никак не нарушает концепцию. Создавая свой сигнал и слот, мы тоже нарушаем концепции? Улыбающийся

Все это конечно ИМХО, возможно в скором будущем ко мне придет понимание того, что написать лишний код - это по феншую, но пока, мну другого мнения Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июль 07, 2013, 16:44 »

просто и элегантно это сделать в python:

Что же в Qt(с++):
Код:
//изврат же!
Это чисто "вкусовое" ощущение (печать прошлого опыта), и оно быстро пройдет  Улыбающийся
Записан
Nuclears
Гость
« Ответ #10 : Июль 07, 2013, 16:50 »

просто и элегантно это сделать в python:

Что же в Qt(с++):
Код:
//изврат же!
Это чисто "вкусовое" ощущение (печать прошлого опыта), и оно быстро пройдет  Улыбающийся

Возможно Улыбающийся
Т.е. это действительно самый "элегантный" способ, [теперь] знакомый сообществу http://www.prog.org.ru/ ?
Подожду еще, может кто наставит на путь истинный правильным, мотивированным предложением Улыбающийся
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #11 : Июль 07, 2013, 16:54 »

Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды.
упомянутый уже QSignalMapper; setObjectName() на крайний случай. С++ это не пайтон, смирись.
Прекрасно понимаю, что это классика C++, тем не менее лямбда из моего кода тоже функциональна.
Но кроме этих возможностей, может еще есть какие либо решения данной задачи? Неужели все дружно используют QSignalMapper? Улыбающийся
Плодить код ради кода, меня такой подход в c++ настораживает Улыбающийся
еще один подход — создать хэш вида QHash<QPushButton *, K>, но от написания отдельного слота это не избавит. меньше всего символов уйдет на написание лямбды, но их тоже не нужно тулить сплошь и рядом: например если понадобится вызвать слот руками, то прозрачнее будет написать обычный вызов метода, чем загонять его сначала в лямбду, а потом уже вызывать ее.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Nuclears
Гость
« Ответ #12 : Июль 07, 2013, 17:07 »

...но их тоже не нужно тулить сплошь и рядом: например если понадобится вызвать слот руками, то прозрачнее будет написать обычный вызов метода, чем загонять его сначала в лямбду, а потом уже вызывать ее.
Почему же, при прямом вызове слота, параметр может быть пустым, что будет описано в самом слоте (проверка входящего параметра), т.е. это не требует написания ламбда функции -> дергать слот можем как и где угодно.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #13 : Июль 07, 2013, 17:21 »

я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #14 : Июль 07, 2013, 18:17 »

Плодить код ради кода, меня такой подход в c++ настораживает Улыбающийся
Я вот вообще тебя не понимаю, на каждое соединение для тыщи кнопок тебя не напрягает плодить код (передава в лямбду параметра слота.
А использовать компактную запись с использованием QSignalMaper тебя напрягает.

Посмотри пример Калькулятор в поставке Qt там всё компактно
Записан

Юра.
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.065 секунд. Запросов: 23.