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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: lambda функция слота clicked  (Прочитано 14483 раз)
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


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

Представь таблицу в которой толпа строк, допустим 3 столбца, первый некое значение, второй некое значение, третий кнопка, при нажатии которой некое значение передаётся в слот, что-то исполнятся и таблица полностью перестраивается.
вот давай о сути. Мне думается что если ты объяснишь некоторые подробности, то решение не заставит себя долго ждать.

как у тебя реализована таблица это представление или это виджет?

Если представление, то в делегате формирующем кнопку делаем один слот, он читает данные из нужного столбца своей строки (из модели), посылает заранее созданный сигнал имеющий параметр (в нём передаётся значение нужного столбца).
К этому сигналу ты и подключаешь свой слот SomeFunc(param)
Записан

Юра.
Nuclears
Гость
« Ответ #16 : Июль 07, 2013, 19:05 »

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

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

Посмотри пример Калькулятор в поставке Qt там всё компактно
Зачем плодить, в цикле же генерация объектов, методов и параметров происходит Улыбающийся
Смотрел на него только в поставке PySide, если не забуду гляну в Qt Улыбающийся

Представь таблицу в которой толпа строк, допустим 3 столбца, первый некое значение, второй некое значение, третий кнопка, при нажатии которой некое значение передаётся в слот, что-то исполнятся и таблица полностью перестраивается.
вот давай о сути. Мне думается что если ты объяснишь некоторые подробности, то решение не заставит себя долго ждать.

как у тебя реализована таблица это представление или это виджет?

Если представление, то в делегате формирующем кнопку делаем один слот, он читает данные из нужного столбца своей строки (из модели), посылает заранее созданный сигнал имеющий параметр (в нём передаётся значение нужного столбца).
К этому сигналу ты и подключаешь свой слот SomeFunc(param)
На примере таблицы - виджет был. Про модель уже нашел отличный пример генерации модели с виджетами.
Но сути, пока, не поменяло, допустим условие другое: 1000 кликабельных QLabel, генерация динамическая, передача в слот параметра при сигнале clicked без сигналмаппера.

Еще раз напоминаю: я пытаюсь рассмотреть общий случай передачи в слот параметра, при отсутствии параметра у сигнала.
Записан
kamre
Частый гость
***
Offline Offline

Сообщений: 233


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

Может что-то не так понял, но чем не подходит вот такой вариант:
Код
C++ (Qt)
#include <QApplication>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
 
class Widget: public QWidget {
   QLabel *label;
public:
   Widget() {
       label = new QLabel("nothing");
       auto layout = new QVBoxLayout();
       layout->addWidget(label);
       const int n = 5;
       for (int i = 0; i < n; ++i) {
           auto button = new QPushButton(QString::number(i));
           layout->addWidget(button);
           connect(button, &QPushButton::clicked, [=] (bool) {
               setText(QString("button %1 clicked").arg(i));
           });
       }
       setLayout(layout);
   }
   void setText(const QString &text) {
       label->setText(text);
   }
};
 
int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   Widget widget;
   widget.show();
   return app.exec();
}
 
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



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

я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды
Нет, слот описывать как лямбду не зачем, мы же о лямбде в коннекте говорим Улыбающийся
твоя лямбда ведь и является по сути слотом (т.е. методом, который вызывается при нажатии на кнопку). вот если захочется тебе вызвать этот метод из другого места кода, то придется либо лямбду засовывать в переменную либо вызывать некрасивое button->click().

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

хэш-то чем не устроил (или objectName)? кода явно будет меньше чем при использовании сигналмаппера.

и кстати не надо забывать, что лямбды-слоты только в Qt 5 работают.
Записан

Изучением 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
Гость
« Ответ #19 : Июль 07, 2013, 22:14 »

Может что-то не так понял, но чем не подходит вот такой вариант:

no matching function for call to 'Widget::connect(QPushButton*&, void (QAbstractButton::*)(bool), Widget::Widget()::<lambda(bool)>)'
Да и вообще в Qt5.0.2 сначала отказался компилироваться.


UPD: совсем забыл параметры компилятору дать Улыбающийся
Код полностью исправен. Т.е. это действительно самый простой вариант для таких случаев?
« Последнее редактирование: Июль 07, 2013, 22:19 от Nuclears » Записан
Nuclears
Гость
« Ответ #20 : Июль 07, 2013, 22:30 »

я имею в виду что если ты опишешь слот как лямбду, а не как метод, то придется заводить поле в классе для этой лямбды
Нет, слот описывать как лямбду не зачем, мы же о лямбде в коннекте говорим Улыбающийся
твоя лямбда ведь и является по сути слотом (т.е. методом, который вызывается при нажатии на кнопку). вот если захочется тебе вызвать этот метод из другого места кода, то придется либо лямбду засовывать в переменную либо вызывать некрасивое button->click().
А разве вызов метода click() объекта противоречит дзену ООП? Думал совсем наоборот Улыбающийся

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

хэш-то чем не устроил (или objectName)? кода явно будет меньше чем при использовании сигналмаппера.

Честно, мну все еще плохо понимает типы данных C++ и создавать такие вещи просто пока не научился Улыбающийся
и кстати не надо забывать, что лямбды-слоты только в Qt 5 работают.
Ну это понятно, к тому же мой вариант лямбды из C++11
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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


NB: Вопрос состоит в том, как просто и элегантно передать в слот параметры, при сигнале не имеющего параметров, а не в  "идеологии" этого процесса. Почитайте информацию по ссылкам, все встанет на свои места.

Курить в сторону std::bind? http://en.cppreference.com/w/cpp/utility/functional/bind
Записан

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

Arch Linux Plasma 5
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #22 : Июль 08, 2013, 15:36 »

это действительно самый простой вариант для таких случаев?
Можно еще вот так через std::bind:
Код
C++ (Qt)
#include <QApplication>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
 
#include <functional>
 
int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   auto label = new QLabel("nothing");
   auto layout = new QVBoxLayout();
   layout->addWidget(label);
   const int n = 10;
   for (int i = 0; i < n; ++i) {
       auto button = new QPushButton(QString::number(i));
       layout->addWidget(button);
       auto text = QString("button %1 clicked").arg(i);
       QObject::connect(button, &QPushButton::clicked,
                        std::bind(&QLabel::setText, label, text));
   }
   QWidget widget;
   widget.setLayout(layout);
   widget.show();
   return app.exec();
}
 
« Последнее редактирование: Июль 08, 2013, 15:51 от kamre » Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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