PDA

View Full Version : connect() - connecting to slot and passing arguments



Tomasz
6th September 2010, 22:43
Hello!

I've got function:



int myFunc(QString *param)
{
[...]
}


and I want to connect that function to two different buttons, which will pass two different QString arguments. How can I do that?



connect(button1, SIGNAL(clicked()), this, ?myFunc()?);
connect(button2, SIGNAL(clicked()), this, ?myFunc()?);


Lets say that button1 should pass to function "abc" and button2 "def".

thanks in advance
best regards
Tomasz

Zlatomir
6th September 2010, 23:37
If i understood right, the best answer is signal mapper (http://doc.trolltech.com/4.6/qsignalmapper.html)
LE: You can also sub-class and connect the clicked signal with some signal you define with default arguments.

Tomasz
7th September 2010, 09:37
I've read about signal mapper and I think this is the answer. But I don't understand how should I do it. Some piece of code would be very useful.

thanks in advance
best regards
Tomasz

Lykurg
7th September 2010, 09:39
Isn't the example of the docs (detailed description of QSignalMapper) enough?
ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);

QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}

connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));

setLayout(gridLayout);
}

Tomasz
7th September 2010, 10:18
I've read this, but to be more specyfic I don't know how to use it. My code will look like this:



ButtonWidget::ButtonWidget(QString text, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);

QPushButton *button = new QPushButton(texts);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, text);

connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));
}


And then in my code I'm doing something like this:



ButtonWidget *btn = new ButtonWidget("test");


and then:


connect(btn, signal(clicked()), this, SLOT(myFunc(String *param)));


right? And this will pass arguments? Or am I wrong?

thanks in advance
best regards
Tomasz

thanks in advance
best regards
Tomasz

Lykurg
7th September 2010, 10:23
right? And this will pass arguments? Or am I wrong?Try it and you will see.

QPushButton *button = new QPushButton(texts);
there is a 's' too much.

connect(btn, signal(clicked()), this, SLOT(myFunc(String *param)));
You don't need that since the mapper does the work for you. therefore you have
connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));

Tomasz
7th September 2010, 10:50
Yes, You're right about 's'. I've done it like this:



#include "nowyGuzik.h"

nowyGuzik::nowyGuzik(QString text, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);

QPushButton *button = new QPushButton(text);
button->setGeometry(0,0,40,40);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, text);

connect(signalMapper, SIGNAL(mapped(const QString &)), this, SIGNAL(clicked(const QString &)));
}


and in my code:



nowyGuzik *btn = new nowyGuzik("test");
ui->verticalLayout->addWidget(btn);


And I can't see any button. And still don't know how to connect that signal with my function. Sorry for my stupid questions but I've never used this signal mapper thing and still don't understand everything.

Lykurg
7th September 2010, 11:43
button->setGeometry(0,0,40,40);Use a layout. Maybe you don't see the button since it is misplaced.



connect(signalMapper, SIGNAL(mapped(const QString &)), this, SIGNAL(clicked(const QString &)));
"clicked()" is your slot! You have to define it and use SLOT instead of SIGNAL.

Tomasz
7th September 2010, 12:25
Yes, You're again right! Problems with layout - button was opening in new window. Now I've got everything like this:



button = new QPushButton;
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, "test");
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(myFun(QString)));


and a couple lines down I've got:



void MainWindow::myFun(QString parameter)
{
[...]
}


And console give's me:



Object::connect: No such slot MainWindow::myFun(QString *parameter)
Object::connect: (receiver name: 'MainWindow')


What I'm doing wrong?


----------------------------------------------OK, solved my stupid mistake

Another question - why If I create 4 buttons, and I click one my function is triggered 4 times? Should I have separate QSignalMapper for all buttons?

thanks in advance
best regards
Tomasz

Zlatomir
7th September 2010, 12:37
Did you declare "void MainWindow::myFun(QString *parameter)" with "public slots:" access specifier, in your class header file?

Tomasz
7th September 2010, 12:42
Yes, It's public. I'm creating my buttons like this:



guziki1 = new QPushButton;
connect(guziki1, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(guziki1, "test");
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(myFun(QString)));

guziki2 = new QPushButton;
connect(guziki2, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(guziki2, "test");
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(myFun(QString)));
[...]


And I'm clicking on button and function is triggered a couple times (as many as I have buttons).

thanks in advance
best regards
Tomasz

Zlatomir
7th September 2010, 12:46
That's because all your mapped signals have the same string: "test"

Tomasz
7th September 2010, 12:53
I've changed string - different for each button:



for (int j=0; j<4; j++)
{
button[j] = new QPushButton;
connect(button[j], SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button[j], QString::number(j));
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(myFun(QString)));
}


And if I click on firs button function is triggered 4 times with '0', on second - four times with '1'. Why?

---------------------------------------------------OK, again solved



connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(myFun(QString)));


should be once.

thanks
best regards
Tomasz