LINUX.ORG.RU

2 параметра из лямбды Qt

 , ,


0

1

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

Main.hpp
---
public slots:
void MySlot(MyCell p1, int i);

Main.cpp
---
MyCell* p1; 
for (int i=0; i<100; i++)
{
connect(p1->but[i], SIGNAL(clicked()), this, [=] () { SLOT(MySlot(p1, i) });
}
void Main::MySlot(MyCell p1, int i) //здесь надо получить значение int из цикла и ссылку на MyCell* p1
{
} 
Вот. Но компилятор выдает ошибку. Что не так я написал, подскажите, пожалуйста, и как передать ссылку на указатель?



Последнее исправление: Rot1 (всего исправлений: 3)

connect(p1->but, &QPushButton::clicked, [=] { MySlot(p1, i); });

Но лучше захватывать умные указатели на this (QPointer) и p1, чтоб не попасть на креш

anonymous
()

Что то ты фигню какую-то написал, намешал старый и новый синтаксис одновременно.

или connect(p1->but, &MyCell::clicked, [](){ MySlot(p1, i) }); либо... Либо сдается мне - тебе нужен QSignalMapper

wolph ★★
()
Ответ на: комментарий от anonymous

что здесь поменялось, без «this» и "()" попробовать?

Rot1
() автор топика
Ответ на: комментарий от wolph

а где в моем коде старый синтаксис? Я можно сказать новенький в qt

Rot1
() автор топика
Ответ на: комментарий от wolph

c QSignalMapper не работал никогда. Не знаешь, где можно почитать доходчивое объяснение по поводу этого класса?

Rot1
() автор топика
Ответ на: комментарий от Rot1

В доке. Можешь тут http://doc.qt.io/qt-5/qsignalmapper.html. А можешь просто в QtCreator нажать F1 и вбить имя интересующего тебю класса. Там и пример будет, кмк - это как раз твой случай.

wolph ★★
()

Даже если вы исправите метод connect(), то всё равно так делать нельзя. p1 и i должен испускать сигнал.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

А что я в нем прописал неправильно? И почему нельзя? У меня получалось передать один i...

Rot1
() автор топика
Ответ на: комментарий от Rot1

Читайте книжки по Qt. Вы совершенно неверно используете сигналы-слоты. Тут сложно объяснить на пальцах.

RazrFalcon ★★★★★
()

Наверное

Вы из цикла должны кидать сигнал, вроде

emit sendIndex(p1, 1);

А вообще у вас сигнатуры сигнала и слота не совпадают. Сделайте их одинаковыми и идентифицируйте отправителя (и индекс, если он будет нужен) с помощью QObject::sender() в самом слоте. Индекс можно будет прикрепить, заюзав http://doc.qt.io/qt-5/qobject.html#setProperty (к примеру).

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 2)
Ответ на: Наверное от EXL

я переписал connect так: connect(p1->but[1], &PushButton::clicked, thus, [this, p1, i] () {MySlot(p1, i); });. Это тоже неверно? У меня ошибку выдает компилятор «no matching function for call to 'Main::MySlot(MyCell* const&, const int&)'. Ее никак не исправить разве?

Rot1
() автор топика
Ответ на: Наверное от EXL

у меня сигнал отправляет один класс, а индекс нужен из класса, который находится над ним. Поэтому если я идентифицирую отправителя, то я не смогу присвоить ему индекс. Мне нужно идентифицировать класс, из которого другой класс отправляет сигнал

Rot1
() автор топика
Ответ на: комментарий от Rot1

да и для моей задачи нужно получить именно содержание массива, а не один элемент для него с индексом

Rot1
() автор топика

ты что-то вообще херню написал. SLOT на самом деле это макрос, который превратится в дальнейшем в строку. как и SIGNAL и METHOD.

connect(sender, SIGNAL(xxxx), this, SLOT(MySlot());
или 
connect(sender, SIGNAL(xxxx), SLOT(MySlot());//он автоматом коннектит на this.

сигнатуры поправь чтоб совпадало. у тебя clicked() дает 0 параметров и принимать можно столько же(можно меньше - toggled(bool) можно цеплять на foo(bool) и на foo2() например)

i36_zubov
()
Ответ на: комментарий от Rot1

Я не знаю, что ты там пытаешься сделать, но слоты работают таким образом (старый синтаксис):

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QPushButton *pushButtons[100];
    for (int i = 0; i < 100; ++i) {
        pushButtons[i] = new QPushButton(this);
        pushButtons[i]->setText(QString("butt%1").arg(i));
        pushButtons[i]->setProperty("index", i);
        ui->gridLayout->addWidget(pushButtons[i], i % 10, i / 10);
        connect(pushButtons[i], SIGNAL(clicked(bool)), this, SLOT(MySlot(bool)));
    }
}

void MainWindow::MySlot(bool)
{
    QString buttonText = qobject_cast<QPushButton*>(QObject::sender())->text();
    QString index = QObject::sender()->property("index").toString();
    ui->label->setText(QString("Btn name: ") + buttonText + QString(" index: ") + index);
}
EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 2)

Всем спасибо, wolph'y и ананимусу, что написал первым, лично. Переписал connect, как они советовали. НО следовало также присвоить указатель MyCell'у в инструкции метода и блоке public slots, и 2 нужных мне параметра благополучно передались.

Rot1
() автор топика
Ответ на: комментарий от EXL

Это то я и сам могу написать. У меня в классе находится другой класс с кнопками. И задача стоит получить массив ВСЕХ кнопок, а не одну (ячейку с ее индексом). Проблема уже решена. Спасибо

Rot1
() автор топика
Ответ на: комментарий от i36_zubov

Я знаю на счет сигнатур сигнала и слота, и как там передаются данные. Чтобы их не поправлять(те самые сигнатуры у сигнала клика), было принято решение использовать лямбда-функцию, в чем, собственно, и стоял вопрос топика.

Rot1
() автор топика
Ответ на: комментарий от i36_zubov

да, там, в параметрах, должен был быть MyCell и int, как и у клика. Но дело в том, что в примере кода, который я дал, я пытался написать лямбда функцию. И как выяснилось, делал это неверно

Rot1
() автор топика

ссылку на myCell можно получить в слоте так MyCell* cell = qobject_cast<MyCell*>(this->sender)

SIGNAL(clicked())
SLOT(MySlot(p1, i)

- это старый синтаксис, с проверкой в рантайме, лучше использовать новый &TypeSrc::singalName &TypeDst::slotName

anonymous
()
Ответ на: комментарий от anonymous

ссылку на myCell можно получить в слоте так MyCell* cell = qobject_cast<MyCell*>(this->sender)

Это если получатель объект, а не лямбда. Иначе даже если захватить this - sender для него может быть nullptr или мусором.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.