Название: lambda функция слота clicked Отправлено: Nuclears от Июль 06, 2013, 21:47 Итак, с совсем недавнего времени перешел на Qt, с++ не знаю совсем, вообщем очередное пополнение среди быдлокодеров :)
Перейдем к делу. просто и элегантно это сделать в python: Код: self.Button.clicked.connect(lambda : self.SomeFunc(param)) Что же в Qt(с++): Код: //изврат же! Существует ли более изящный способ? Нечто такое, которое естественно не работает, т.к. нет параметров у сигнала. Код: 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: Вопрос состоит в том, как просто и элегантно передать в слот параметры, при сигнале не имеющего параметров, а не в "идеологии" этого процесса. Почитайте информацию по ссылкам, все встанет на свои места. Название: Re: lambda функция слота clicked Отправлено: lit-uriy от Июль 07, 2013, 01:09 Си++ это Си++
Пиши в его стиле. Сделай слот (функцию-член класса), к нему и цепляйся. Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 09:20 Си++ это Си++ Он такой же суровый как питон, не воспринимающий табуляцию :)Пиши в его стиле. Сделай слот (функцию-член класса), к нему и цепляйся. Неужели на каждое действие(однотипное с переменной) необходим свой слот? Конструкция с лямбдой у мну работает, но вопрос в ее "изяществе" и поведении в исключительных ситуациях. Да и новый тип сигнал/слот в qt5 тонко намекает, что использование лямбд упрощает жизнь и код :) Название: Re: lambda функция слота clicked Отправлено: lit-uriy от Июль 07, 2013, 14:07 >>новый тип сигнал/слот в qt5 тонко намекает, что использование лямбд упрощает жизнь и код
не согласен. Приведённый тобою код на Си++ (нового стандарту) ниразу не понятен. Что там за проверка на "Не щёлкнули"? с чего тогда сигнал был послан? >>Неужели на каждое действие(однотипное с переменной) необходим свой слот На каждое событие (сигнал), а не на каждое действие. Слот может быть и один, и в нём можно многое разруливать. А вообще стоит подумать над имеющейся архитектурой, нужна ли функция SomeFunc вообще? Может лучше сделать подходящий слот? Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 15:40 >>Приведённый тобою код на Си++ (нового стандарту) ниразу не понятен. Что там за проверка на "Не щёлкнули"? с чего тогда cигнал был послан?
Мой код лямбды не нового стандарта. bool clicked можно заменить на bool matumba, это просто лябда, и никакого отношения к сигналу не имеет. Новый стандарт мну упомянул для примера, в котором нет функционала, когда сигнал не имеет параметров, а передать в слот нужно какой-то параметр. >>На каждое событие (сигнал), а не на каждое действие. >>Слот может быть и один, и в нём можно многое разруливать. Именно это и пытаюсь сделать, создав один слот, в который можно передать параметр. А передать параметр можно только тогда, когда у сигнала он есть. Посмотри код внимательно, испытай код, сразу станет понятно. >>А вообще стоит подумать над имеющейся архитектурой, нужна ли функция SomeFunc вообще? Может лучше сделать подходящий слот? SomeFunc - это ни что иное как слот, по коду этого не видно? Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды. Название: Re: lambda функция слота clicked Отправлено: m_ax от Июль 07, 2013, 16:11 Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды. Идеология сигнально-слотового механизма (когда его придумывали) подразумевает, касательно описанного случая, следующее: Когда кнопку "нажали", то ей вообще фиолетово, кто подписан на её сигнал "меня нажали". Если логика вашего подхода требует по мимо этого, какие то дополнительные связи между сендером и рецийвером, то скорее всего - это следствие похоспроектированной архитектуры.. То, о чём говорил lit-uriy Потом, при объявлении лямды, она должна знать о вашем "param", что уже накладывает связь между сендером и получателем.. Что, в свою очередь, противоречить концепции сигнально-слотового механизма.. В идеале, ни тот, кто посылает сигнал, ни тот, кто его принимает, ничего не должен знать друг о друге. Название: Re: lambda функция слота clicked Отправлено: kambala от Июль 07, 2013, 16:13 Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды. упомянутый уже QSignalMapper; setObjectName() на крайний случай. С++ это не пайтон, смирись.Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 16:27 Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды. упомянутый уже QSignalMapper; setObjectName() на крайний случай. С++ это не пайтон, смирись.Но кроме этих возможностей, может еще есть какие либо решения данной задачи? Неужели все дружно используют QSignalMapper? :) Плодить код ради кода, меня такой подход в c++ настораживает :) Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 16:39 Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды. Идеология сигнально-слотового механизма (когда его придумывали) подразумевает, касательно описанного случая, следующее: Когда кнопку "нажали", то ей вообще фиолетово, кто подписан на её сигнал "меня нажали". Если логика вашего подхода требует по мимо этого, какие то дополнительные связи между сендером и рецийвером, то скорее всего - это следствие похоспроектированной архитектуры.. То, о чём говорил lit-uriy Потом, при объявлении лямды, она должна знать о вашем "param", что уже накладывает связь между сендером и получателем.. Что, в свою очередь, противоречить концепции сигнально-слотового механизма.. В идеале, ни тот, кто посылает сигнал, ни тот, кто его принимает, ничего не должен знать друг о друге. Почему же сразу говорим "это следствие похоспроектированной архитектуры" новому былдокодеру? :) Представь таблицу в которой толпа строк, допустим 3 столбца, первый некое значение, второй некое значение, третий кнопка, при нажатии которой некое значение передаётся в слот, что-то исполнятся и таблица полностью перестраивается. Классикой - сигнал маппер, отлавливаем и передаем в слот, принимающий уже от сигналмаппера значение. Либо создать столько же слоток как и кнопок -> это уже, конечно, суицидальный метод. Лямбдой же прямо в слот передаем значение, делаем что-то. В этом случаем мы пропускаем ненужный фильтр. Утрировано - экономим процессорное время. При динамеском создании param берется опять же как и все остальные данные, из источника создания динамики. Это никак не нарушает концепцию. Создавая свой сигнал и слот, мы тоже нарушаем концепции? :) Все это конечно ИМХО, возможно в скором будущем ко мне придет понимание того, что написать лишний код - это по феншую, но пока, мну другого мнения :) Название: Re: lambda функция слота clicked Отправлено: Igors от Июль 07, 2013, 16:44 просто и элегантно это сделать в python: Это чисто "вкусовое" ощущение (печать прошлого опыта), и оно быстро пройдет :)Что же в Qt(с++): Код: //изврат же! Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 16:50 просто и элегантно это сделать в python: Это чисто "вкусовое" ощущение (печать прошлого опыта), и оно быстро пройдет :)Что же в Qt(с++): Код: //изврат же! Возможно :) Т.е. это действительно самый "элегантный" способ, [теперь] знакомый сообществу http://www.prog.org.ru/ ? Подожду еще, может кто наставит на путь истинный правильным, мотивированным предложением :) Название: Re: lambda функция слота clicked Отправлено: kambala от Июль 07, 2013, 16:54 Допустим динамически создаем 1000 кнопок, все они при клике должны передать в слот некий уникальный параметр, напиши пример такого коннекта без лямбды. упомянутый уже QSignalMapper; setObjectName() на крайний случай. С++ это не пайтон, смирись.Но кроме этих возможностей, может еще есть какие либо решения данной задачи? Неужели все дружно используют QSignalMapper? :) Плодить код ради кода, меня такой подход в c++ настораживает :) Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 17:07 ...но их тоже не нужно тулить сплошь и рядом: например если понадобится вызвать слот руками, то прозрачнее будет написать обычный вызов метода, чем загонять его сначала в лямбду, а потом уже вызывать ее. Почему же, при прямом вызове слота, параметр может быть пустым, что будет описано в самом слоте (проверка входящего параметра), т.е. это не требует написания ламбда функции -> дергать слот можем как и где угодно.Название: Re: lambda функция слота clicked Отправлено: kambala от Июль 07, 2013, 17:21 я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды
Название: Re: lambda функция слота clicked Отправлено: lit-uriy от Июль 07, 2013, 18:17 Плодить код ради кода, меня такой подход в c++ настораживает :) Я вот вообще тебя не понимаю, на каждое соединение для тыщи кнопок тебя не напрягает плодить код (передава в лямбду параметра слота.А использовать компактную запись с использованием QSignalMaper тебя напрягает. Посмотри пример Калькулятор в поставке Qt там всё компактно Название: Re: lambda функция слота clicked Отправлено: lit-uriy от Июль 07, 2013, 18:25 Представь таблицу в которой толпа строк, допустим 3 столбца, первый некое значение, второй некое значение, третий кнопка, при нажатии которой некое значение передаётся в слот, что-то исполнятся и таблица полностью перестраивается. вот давай о сути. Мне думается что если ты объяснишь некоторые подробности, то решение не заставит себя долго ждать.как у тебя реализована таблица это представление или это виджет? Если представление, то в делегате формирующем кнопку делаем один слот, он читает данные из нужного столбца своей строки (из модели), посылает заранее созданный сигнал имеющий параметр (в нём передаётся значение нужного столбца). К этому сигналу ты и подключаешь свой слот SomeFunc(param) Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 19:05 я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды Нет, слот описывать как лямбду не зачем, мы же о лямбде в коннекте говорим :)Плодить код ради кода, меня такой подход в c++ настораживает :) Я вот вообще тебя не понимаю, на каждое соединение для тыщи кнопок тебя не напрягает плодить код (передава в лямбду параметра слота.А использовать компактную запись с использованием QSignalMaper тебя напрягает. Посмотри пример Калькулятор в поставке Qt там всё компактно Смотрел на него только в поставке PySide, если не забуду гляну в Qt :) Представь таблицу в которой толпа строк, допустим 3 столбца, первый некое значение, второй некое значение, третий кнопка, при нажатии которой некое значение передаётся в слот, что-то исполнятся и таблица полностью перестраивается. вот давай о сути. Мне думается что если ты объяснишь некоторые подробности, то решение не заставит себя долго ждать.как у тебя реализована таблица это представление или это виджет? Если представление, то в делегате формирующем кнопку делаем один слот, он читает данные из нужного столбца своей строки (из модели), посылает заранее созданный сигнал имеющий параметр (в нём передаётся значение нужного столбца). К этому сигналу ты и подключаешь свой слот SomeFunc(param) Но сути, пока, не поменяло, допустим условие другое: 1000 кликабельных QLabel, генерация динамическая, передача в слот параметра при сигнале clicked без сигналмаппера. Еще раз напоминаю: я пытаюсь рассмотреть общий случай передачи в слот параметра, при отсутствии параметра у сигнала. Название: Re: lambda функция слота clicked Отправлено: kamre от Июль 07, 2013, 20:17 Может что-то не так понял, но чем не подходит вот такой вариант:
Код
Название: Re: lambda функция слота clicked Отправлено: kambala от Июль 07, 2013, 22:11 я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды Нет, слот описывать как лямбду не зачем, мы же о лямбде в коннекте говорим :)Еще раз напоминаю: я пытаюсь рассмотреть общий случай передачи в слот параметра, при отсутствии параметра у сигнала. и кстати не надо забывать, что лямбды-слоты только в Qt 5 работают. Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 22:14 Может что-то не так понял, но чем не подходит вот такой вариант: no matching function for call to 'Widget::connect(QPushButton*&, void (QAbstractButton::*)(bool), Widget::Widget()::<lambda(bool)>)' Да и вообще в Qt5.0.2 сначала отказался компилироваться. UPD: совсем забыл параметры компилятору дать :) Код полностью исправен. Т.е. это действительно самый простой вариант для таких случаев? Название: Re: lambda функция слота clicked Отправлено: Nuclears от Июль 07, 2013, 22:30 я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды Нет, слот описывать как лямбду не зачем, мы же о лямбде в коннекте говорим :)Еще раз напоминаю: я пытаюсь рассмотреть общий случай передачи в слот параметра, при отсутствии параметра у сигнала. Честно, мну все еще плохо понимает типы данных C++ и создавать такие вещи просто пока не научился :) и кстати не надо забывать, что лямбды-слоты только в Qt 5 работают. Ну это понятно, к тому же мой вариант лямбды из C++11Название: Re: lambda функция слота clicked Отправлено: m_ax от Июль 07, 2013, 22:40 NB: Вопрос состоит в том, как просто и элегантно передать в слот параметры, при сигнале не имеющего параметров, а не в "идеологии" этого процесса. Почитайте информацию по ссылкам, все встанет на свои места. Название: Re: lambda функция слота clicked Отправлено: kamre от Июль 08, 2013, 15:36 это действительно самый простой вариант для таких случаев? Можно еще вот так через std::bind:Код
|