QObject::connect: No such slot (Qt, C++) - c++

I can run the program but the button cannot access the send function. I get this hint:
QObject::connect: No such slot Mail::send(emailInput, pwdInput)
Someone knows what's my mistake?
mail.h:
#ifndef MAIL_H
#define MAIL_H
#include <QWidget>
namespace Ui {
class Mail;
}
class Mail : public QWidget
{
Q_OBJECT
public:
explicit Mail(QWidget *parent = 0);
~Mail();
public slots:
void send(std::string email, std::string pwd);
private:
Ui::Mail *ui;
};
#endif // MAIL_H
mail.cpp:
Mail::Mail(QWidget *parent) :
QWidget(parent)
{
QLineEdit *edt1 = new QLineEdit(this);
grid->addWidget(edt1, 0, 1, 1, 1);
std::string emailInput = edt1->text().toStdString();
...
QObject::connect(acc, SIGNAL(clicked()),this, SLOT(send(emailInput, pwdInput)));
}
void Mail::send(std::string email, std::string pwd){
...
}

In fact, you have 2 mistakes in your code:
the SLOT macro takes the type of arguments as parameter not their name, then the code should be : SLOT(send(std::string, std::string)).
You try to connect a SIGNAL which has less argument than the SLOT which is impossible.
In order to avoid all these problems you can use the new signal/slot syntax (if your are using Qt5):
QObject::connect(acc, &QLineEdit::clicked, this, &Mail::onClicked);
I also invite you to use the QString class instead of std::string when working with Qt, it is a lot easier.

That depends on what you want to do:
If emailInput and pwdInput come from widgets, you have to write an intermediate slot that will get the values and call send.
If they are local variables, the easiest is probably to use a lambda.

Should be
QObject::connect(acc, SIGNAL(clicked()),this, SLOT(send(std::string, std::string)));
Macros SIGNAL and SLOT expect method's signature as argument(s).
Additionally, you can connect a signal to a slot of less arity, not the vice versa; here, QObject would not simply know what should be substituted for slot's arguments. You can use the overload of connect that accepts an arbitrary Functor (an anonymous closure, most likely) as slot:
QObject::connect(acc, SIGNAL(clicked()), [=](){ send(std::string(), std::string()); });
Thirdly, were you to use QString instead of std::string, you would not have that heavy copy overhead when passing by value.

Related

How can I emit a signal of another instance from _clicked() event?

the runnable project is here:
enter link description here
I sincerely glad to have your detail answers to solve this, but I am still confusing on this issue:
case 1: changing socket_session as a member variable of mainwindow
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
SocketThread* socket_session;
private:
...
But this is not the solution to access setFlag, even after I change the `Form1::on_qpushButton__set_white_level_0_clicked()' function like this:
void Form1::on_qpushButton__set_white_level_0_clicked() {
qDebug() <<"clicked()";
socket_session->setThreadFlag(true);
}
Still it doesn't make sense because form1 instance doesn't have "the" instance of socket_thread which has been instantiated from mainwindow.
There's a solution I think is making another class that includes all instances that I want to use from inside of mainwindow but I don't think that is a good one because I am using thread and accessing a global big instance class that includes all of them to be "shared" is not a good idea for someone like me.
#include <form1.h>
#include <ui_form1.h>
#include "socketthread.h"
Form1::Form1(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form1) {
ui->setupUi(this);
}
Form1::~Form1() {
delete ui;
}
void Form1::on_qpushButton__set_white_level_0_clicked() {
qDebug() <<"clicked()";
socket_session->setThreadFlag(true);
}
enter image description here
I know I am lack of understanding about this but, do I wanna make something nobody does...? I think everyone wants to separate all objects and their methods clearly and communicate via signals or calling functions from delivered object instances...
case 2: ... let me try how you suggested make possible first...
I can read C++ code and overall structure, but I don't know why I have to struggle with this, so please help me, dear Guru.
On socketthread.h :
class SocketThread : public QThread {
Q_OBJECT
public:
QTcpSocket *socket_session;
SocketThread();
~SocketThread(){}
bool connectToServer(QString, int);
void sendData(const char*, int, int);
void run(void);
private:
QString message;
volatile bool threadFlag;
signals:
void changedThreadFlag(void);
void changedMessageStr(void);
void setThreadFlag(bool);
void setMessageStr(QString);
private slots:
void setStr(QString);
void setFlag(bool);
void socketError(QAbstractSocket::SocketError);
};
And its implementation is...
SocketThread::SocketThread() {
socket_session = NULL;
threadFlag = false;
message = "NULL";
connect(this, SIGNAL(setThreadFlag(bool)), this, SLOT(setFlag(bool)));
}
...
void SocketThread::setStr(QString str) {
message = str;
}
void SocketThread::setFlag(bool flag) {
threadFlag = flag;
}
void SocketThread::run() {
while(true) {
if(threadFlag) {
QThread::msleep(100);
qDebug() << message;
} else
break;
}
qDebug() << "loop ended";
}
And I have one form which has a button, and I put a clicked() slot of it like this...
void Form1::on_qpushButton__set_white_level_0_clicked() {
qDebug() <<"clicked()";
--how can I emit the signal of the one of socketthread from here??
}
Now, the mainwindow is like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
QString addr_server = "223.194.32.106";
int port = 11000;
SocketThread* socket_session = new SocketThread();
socket_session->connectToServer(addr_server, port);
ui->setupUi(this);
Form1* form1;
form1 = new Form1();
ui->stackedWidget_mainwindow->addWidget(form1);
ui->stackedWidget_mainwindow->setCurrentWidget(form1);
socket_session->run();
...
I just simply want to emit the signal setThreadFlag of the socketthread from inside of QPushbutton_clicked() slot.
Once the socket_session->run() started, I need to change the threadFlag by clicking the button by emitting setThreadFlag() of one's from the running thread. And I just stuck in here.
Does it possible even?
Or am I doing this all wrong from the beginning?
As mentioned in this post:
"Emitting a signal" == "calling a function"
So all you really have to do is call the signal function, and all connected slots should be called.
This of course means that the Form1 object needs a pointer to the thread object, i.e. it needs a copy of socket_session. Then you can simply call the signal on the object
socket_session->setThreadFlag(your_flag);
Of course, if the Form1 have a copy of the socket_session pointer, it might as well call setFlag directly, if it was public.
I just simply want to emit the signal setThreadFlag of the socketthread from inside of QPushbutton_clicked() slot.
No signal is needed – just call the function.
void Form1::on_qpushButton__set_white_level_0_clicked() {
qDebug() <<"clicked()";
// --how can I emit the signal of the one of socketthread from here??
// E.g. this way:
socket_session->setThreadFlag(true);
}
To make this possible, another fix is needed:
socket_session is a local variable in OP's exposed code.
To make it "persistent", it has to become e.g. a member variable.
So, the constructor MainWindow::MainWindow() has to be changed:
// Nope: SocketThread* socket_session = new SocketThread();
// Instead:
socket_session = new SocketThread();
and SocketThread* socket_session; has to be added to member variables of class MainWindow.
To make it accessible in Form1, it has to be passed to Form1 as well.
This could be done e.g. by making it a member variable in Form1 also which is initialized with a constructor argument (or set from MainWindow afterwards).
(I must admit that I never have used the Qt UI builder QtDesigner but build all my UIs by C++ code exclusively.)
But, now, another fix is necessary:
volatile doesn't make a variable suitable for interthread communication.
(This was used in ancient times before multi-threading started to be supported by C++11.)
However, this is wrong: Is volatile useful with threads?
An appropriate fix would be to use std::atomic instead:
// Wrong for interthread-com.
//volatile bool threadFlag;
// Correct:
std::atomic<bool> threadFlag; // #include <atomic> needed
FYI: SO: Multithreading program stuck in optimized mode but runs normally in -O0
And, finally, in SocketThread::SocketThread():
connect(this, SIGNAL(setThreadFlag(bool)), this, SLOT(setFlag(bool)));
is not necessary in this case.
SocketThread::setThreadFlag() could call SocketThread::setFlag() directly, or even write threadFlag itself:
void setThreadFlag(bool flag) { threadFlag = flag; }
As I (recommended to) make threadFlag atomic, it can be accessed from any thread without causing a data race.
Update:
After OP has updated the question:
I just simply want to emit the signal setThreadFlag of the socketthread from inside of QPushbutton_clicked() slot.
The button (created from UI Form1) can be connected in the MainWindow as well (without using any method of Form1):
QObject::connect(form1->button1, &QPushButton::clicked,
socket_session, &SocketThread::setThreadFlag,
Qt::QueuedConnection);
Notes:
About form1->button1, I'm not quite sure.
I noticed that widgets in UI generated forms can be accessed this way but I don't know the exact details (as I never used the Qt UI builder on my own).
I used the Qt5 style of QObject::connect().
This is what I would recommend in any case.
The Qt5 style is verified at compile time. –
Wrong connections are detected by the C++ type checking.
Additionally, any function with matching signature can be used – no explicit exposure of slots is anymore necessary.
Even conversion of non-matching signature or adding additional parameters becomes possible by using C++ lambdas which are supported as well.
Qt: Differences between String-Based and Functor-Based Connections
It is possible to connect signals and slots of distinct threads.
I used Qt::QueuedConnection to remark this as interthread communication.
(However, I roughly remember that Qt might be able to detect it itself.
See the doc. for Qt::AutoConnection which is the default.
Further reading: Qt: Signals & Slots
Btw. using the Qt signals for inter-thread communication would exclude the necissity to make SocketThread::threadFlag() atomic. It could become a simple plain bool threadFlag; instead. The slot SocketThread::setThreadFlag() is called in the Qt event loop of QThread, in this case.

How to pass a signal as function parameter?

So i am looking to make our own generic inherited checkbox class that will be able to take in some values in its constructor and pop out a widget that is fully connected to our model in the manner we need.
Currently we do something like this within our view
connect(checkboxWidget, &QCheckbox::Clicked, this, &VMyView::Signal);
Which emits the Signal from VMyView when the checkbox is clicked.
If i wanted to pass that signal as a parameter into my new inherited class to be hooked up in its own connect statement, how would I do so?
Research has shown me i can pass a const char* but i get compilation errors that the signal/slot do not match.
Example
CheckBox(View myView, const char* signal)
{
connect(this, &QCheckBox::Clicked, myView, signal);
}
Returns an error that Signal and slot arguments are not compatible. Ive also tried SIGNAL(signal) with the same result.
The solution ended up being fairly simple in the end
Instead of using this from within my View
connect(pCheckbox, &QCheckBox::clicked, this, &MyView::Signal);
I use
connect(this, &QCheckBox::clicked, View, signal);
Where signal and comes into my function via a function pointer
MyCheckBox::MyCheckBox(QWidget* parent, MyView* View, void(MyView::*signal)(bool))
The key takeaway is
void(MyView::*signal)(bool)
is equal too
&MyView::Signal
I think the major issue here is that signals are not static member functions. Thus they require a pointer to an instance of the class to be called correctly. So you cannot just pass in things like &VMyView::Signal, as there's no corresponding this pointer attached to the function. (This is why most of the QObject::connect() overloads require an instance to the sender/receiver objects.)
One way to solve this is to create a function object, which contains both the member function pointer and the pointer to the object on which to call it. This can be passed to the QObject::connect() function just fine.
Here's an example:
// objects.h
#include <QtCore>
class Receiver : public QObject
{
Q_OBJECT
public:
Receiver( QObject *parent = nullptr)
: QObject(parent)
{
}
~Receiver() { }
signals:
void sig(void);
};
class Sender : public QObject
{
Q_OBJECT
public:
Sender(std::function<void(void)> &bound_signal, QObject *parent = nullptr)
: QObject(parent)
{
// automatically emit `Sender::sig` on a timer, for testing.
timer = new QTimer(this);
timer->setInterval(1000);
QObject::connect(timer, &QTimer::timeout, this, &Sender::sig);
QObject::connect(this, &Sender::sig, bound_signal);
timer->start();
}
~Sender() { }
signals:
void sig(void);
private:
QTimer *timer;
};
And then a main function:
// main.cc
#include <QtCore>
#include "objects.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Receiver receiver; // object to receive the signal
// Bind the receiver's signal to the instance of the class
std::function<void(void)> signal = std::bind(&Receiver::sig, &receiver);
// Create a Sender, which will connect its own signal to the
// given bound signal
Sender sender(signal);
QObject::connect(&receiver, &Receiver::sig,
[]() -> void { qDebug() << "received"; });
return app.exec();
}
So, in your case, the Receiver and its signal would be replaced by VMyView and the signals you want to chain, and Sender would be the custom checkbox class you've implemented. Then in the constructor of the checkbox class, connect whatever signals you want to the given bound signals. You can also pass in a list of bound signals, e.g., std::list<std::function<void(void)>> &bound_signals.
I have to say, though, I'm not sure what this buys you. You'll need to write the connection logic somewhere, and I don't see why it needs to be in the constructor of the checkbox class. Wherever the checkbox and the VMyView class are created and used, that seems like a better place to put the connection code. It's more obvious, less convoluted, and there's better separation of concerns. The checkbox class shouldn't have to know or care what signals/slots its connected to. The application logic (i.e., where the objects are used) should define how the objects interact with one another.

QT4 no such slot error

I know there are many many questions that are just the same, but none of them helps me:
class Form1 : public QMainWindow {
Q_OBJECT
public:
Form1();
virtual ~Form1();
public slots:
void langChange(const char* lang_label);
private:
Ui::Form1 widget;
void setLangStrings();
};
From1 constructor:
Form1::Form1() {
widget.setupUi(this);
connect(widget.btnL0, SIGNAL(clicked(bool)), this, SLOT(langChange("en")));
connect(widget.btnL1, SIGNAL(clicked(bool)), this, SLOT(langChange("fr")));
setLangStrings();
}
And I also have this langChange function implemented:
void Form1::langChange(const char* lang_label)
{
GL_LANG = lang_label;
setLangStrings();
}
I get this stupid error when the connect function is called:
No such slot Form1::langChange("sl") in Form1.cpp:15
I'm using NetBeans with QDesigner for the UI. I must say this QT4 is very difficult to learn.
You simply can't connect SIGNAL with bool as argument to SLOT with const char* as argument. To do this kind of stuff you have to use QSignalMapper. You have an example how to use it inside documentation. In your case, it's very simple, so you should handle it easly.
The SLOT function must have the same signature than the SIGNAL function
Edit: From the official Qt documentation (http://qt-project.org/doc/qt-4.8/signalsandslots.html):
The signature of a signal must match the signature of the receiving
slot. (In fact a slot may have a shorter signature than the signal it
receives because it can ignore extra arguments.)

Can Qt signals return a value?

Boost.Signals allows various strategies of using the return values of slots to form the return value of the signal. E.g. adding them, forming a vector out of them, or returning the last one.
The common wisdom (expressed in the Qt documentation [EDIT: as well as some answers to this question ]) is that no such thing is possible with Qt signals.
However, when I run the moc on the following class definition:
class Object : public QObject {
Q_OBJECT
public:
explicit Object( QObject * parent=0 )
: QObject( parent ) {}
public Q_SLOTS:
void voidSlot();
int intSlot();
Q_SIGNALS:
void voidSignal();
int intSignal();
};
Not only doesn't moc complain about the signal with the non-void return type, it seems to actively implement it in such a way as to allow a return value to pass:
// SIGNAL 1
int Object::intSignal()
{
int _t0;
void *_a[] = { const_cast<void*>(reinterpret_cast<const void*>(&_t0)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
return _t0;
}
So: according to the docs, this thing isn't possible. Then what is moc doing here?
Slots can have return values, so can we connect a slot with a return value to a signal with a return value now? May that be possible, after all? If so, is it useful?
EDIT: I'm not asking for workarounds, so please don't provide any.
EDIT: It obviously isn't useful in Qt::QueuedConnection mode (neither is the QPrintPreviewWidget API, though, and still it exists and is useful). But what about Qt::DirectConnection and Qt::BlockingQueuedConnection (or Qt::AutoConnection, when it resolves to Qt::DirectConnection).
OK. So, I did a little more investigating. Seems this is possible. I was able to emit a signal, and receive value from the slot the signal was connected to. But, the problem was that it only returned the last return value from the multiple connected slots:
Here's a simple class definition (main.cpp):
#include <QObject>
#include <QDebug>
class TestClass : public QObject
{
Q_OBJECT
public:
TestClass();
Q_SIGNALS:
QString testSignal();
public Q_SLOTS:
QString testSlot1() {
return QLatin1String("testSlot1");
}
QString testSlot2() {
return QLatin1String("testSlot2");
}
};
TestClass::TestClass() {
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot1()));
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot2()));
QString a = emit testSignal();
qDebug() << a;
}
int main() {
TestClass a;
}
#include "main.moc"
When main runs, it constructs one of the test classes. The constructor wires up two slots to the testSignal signal, and then emits the signal. It captures the return value from the slot(s) invoked.
Unfortunately, you only get the last return value. If you evaluate the code above, you'll get: "testSlot2", the last return value from the connected slots of the signal.
Here's why. Qt Signals are a syntax sugared interface to the signaling pattern. Slots are the recipients of a signal. In a direct connected signal-slot relationship, you could think of it similar to (pseudo-code):
foreach slot in connectedSlotsForSignal(signal):
value = invoke slot with parameters from signal
return value
Obviously the moc does a little more to help in this process (rudimentary type checking, etc), but this helps paint the picture.
No, they can't.
Boost::signals are quite different from those in Qt. The former provide an advanced callback mechanism, whereas the latter implement the signaling idiom. In the context of multithreading, Qt's (cross-threaded) signals depend on message queues, so they are called asynchronously at some (unknown to the emitter's thread) point in time.
Qt's qt_metacall function returns an integer status code. Because of this, I believe this makes an actual return value impossible (unless you fudge around with the meta object system and moc files after precompilation).
You do, however, have normal function parameters at your disposal. It should be possible to modify your code in such a way to use "out" parameters that act as your "return".
void ClassObj::method(return_type * return_)
{
...
if(return_) *return_ = ...;
}
// somewhere else in the code...
return_type ret;
emit this->method(&ret);
You may get a return value from Qt signal with the following code:
My example shows how to use a Qt signal to read the text of a QLineEdit.
I'm just extending what #jordan has proposed:
It should be possible to modify your code in such a way to use "out" parameters that act as your "return".
#include <QtCore>
#include <QtGui>
class SignalsRet : public QObject
{
Q_OBJECT
public:
SignalsRet()
{
connect(this, SIGNAL(Get(QString*)), SLOT(GetCurrentThread(QString*)), Qt::DirectConnection);
connect(this, SIGNAL(GetFromAnotherThread(QString*)), SLOT(ReadObject(QString*)), Qt::BlockingQueuedConnection);
edit.setText("This is a test");
}
public slots:
QString call()
{
QString text;
emit Get(&text);
return text;
}
signals:
void Get(QString *value);
void GetFromAnotherThread(QString *value);
private slots:
void GetCurrentThread(QString *value)
{
QThread *thread = QThread::currentThread();
QThread *mainthread = this->thread();
if(thread == mainthread) //Signal called from the same thread that SignalsRet class was living
ReadObject(value);
else //Signal called from another thread
emit GetFromAnotherThread(value);
}
void ReadObject(QString *value)
{
QString text = edit.text();
*value = text;
}
private:
QLineEdit edit;
};
To use this, just request call();.
You can try to workaround this with following:
All your connected slots must save their results in some place (container) accessible from signaling object
The last connected slot should somehow (select max or last value) process collected values and expose the only one
The emitting object can try to access this result
Just as an idea.

Binding arguments to signals/slots

I basically have multiple events signals which I want to connect to the same slot. What I want to know is how can I pass string based parameters to that same slot so that the slot knows which is this signal coming from. One alternative is to make as many slots as there are signals and then connect them in a 1:1 manner, but this is efficient, considering that the code for all the processing is very similar. I tried doing this but I'm getting some errors:
connect(selecter1,SIGNAL(selected(QString)),this,SLOT(backgroundTypeChoiceMade(QString)));
connect(button1,SIGNAL(clicked()),this,SLOT(backgroundTypeChoiceMade("button1")));
connect(button2,SIGNAL(clicked()),this,SLOT(backgroundTypeChoiceMade("button2")));
The error is related to the parameters I'm passing in the last 2 commands .. And backgroundTypeChoiceMade is declared like this:
void backgroundTypeChoiceMade(QString);
Can someone tell me what the error is in the above code ?
You can use QSignalMapper. Although the QSignalMapper is the answer to your question, I think jon hanson's answer is the way you should take. You get much more cleaner code that way.
Four methods. One doesn't suck.
QSignalMapper. Works, but makes for messy code.
Named slots. Messy for any significant number of senders, and doesn't work for dynamically-generated senders (e.g., buttons in a list).
sender()-compare. Can handle dynamic senders, but is still kinda ugly.
Subclass the sender. Doesn't suck. Gives you what you really wanted all along: parameterized signals.
Especially when you're using a small number of signals and sender types and when the senders are dynamically generated, subclassing the sender is the cleanest way. This lets you overload the existing signals to contain whatever parameters you need.
And now, wiring up the signals and slots just works:
Keypad::Keypad(QWidget *parent) : QWidget(parent)
{
for (int i = 0; i < 10; ++i)
{
// KeypadButton keeps track of the identifier you give it
buttons[i] = new KeypadButton(i, this);
// And passes it as a signal parameter. Booyah.
connect(buttons[i], SIGNAL(clicked(int)), this, SIGNAL(digitClicked(int)));
}
createLayout();
}
void Keypad::digitClicked(int digit)
{
// The slot can find the clicked button with ease:
dial(button[i]); // or whatever
//...
}
and the extra code is out-of-sight in a subclass you'll never have to touch again.
See http://doc.qt.digia.com/qq/qq10-signalmapper.html#thesubclassapproach for an example implementation of subclassing QPushButton to emit clicked(int) signals. Also discusses all four methods - named slots ("the trivial solution"), sender(), subclassing, and signal mapper.
Caveat: Obviously works best for small numbers of sender types. But that's usually the case. And in that case, it's worth it.
What is inefficient about using separate slots? If there's commonality in the slot handlers then move that into a function, e.g. extending ereOn's example:
void YourClass::YourClass() :
m_button1(new QPushButton()),
m_button2(new QPushButton())
{
connect(m_button1, SIGNAL(clicked()), this, SLOT(yourSlot1()));
connect(m_button2, SIGNAL(clicked()), this, SLOT(yourSlot2()));
}
void YourClass::common(int n)
{
}
void YourClass::yourSlot1()
{
common (1);
}
void YourClass::yourSlot2()
{
common (2);
}
You can't pass constants to connect() because the effective parameters are deduced at execution time, not compile time.
However, while this is against the OO principle, you can use QObject::sender() which gives a pointer to the emitter QObject.
Example below:
void YourClass::YourClass() :
m_button1(new QPushButton()),
m_button2(new QPushButton())
{
connect(m_button1, SIGNAL(clicked()), this, SLOT(yourSlot()));
connect(m_button2, SIGNAL(clicked()), this, SLOT(yourSlot()));
}
void YourClass::yourSlot()
{
if ((QPushButton* button = dynamic_cast<QPushButton*>(sender()))
{
// Now button points to a QPushButton* that you can compare with the pointers you already have
if (button == m_button1)
{
// Whatever
} else
if (button == m_button2)
{
// Whatever
}
}
}
If you have many buttons, you may also use a QSignalMapper by providing an identifier for each button.
You can now really bind a value when connecting. Qt5 added support for that.
Example:
connect(sender, &Sender::valueChanged,
tr1::bind(receiver, &Receiver::updateValue, "senderValue", tr1::placeholder::_1));
See more info.
NB: you can of course use std::bind or boost::bind instead of tr1::bind.
If you really don't want to use QSignalMapper, you could do something like this:
class SignalForwarderWithString: public QObject
{
Q_OBJECT
public:
SignalForwarderWithString(QString data = "", QObject *parent = 0) : QObject(parent), _data(data) {}
QString _data;
signals:
void forward(QString);
public slots:
void receive() { emit forward(_data); }
};
...
connect(selecter1,SIGNAL(selected(QString)),this,SLOT(backgroundTypeChoiceMade(QString)));
SignalForwarderWithString *sfws;
sfws = new SignalForwarderWithString("button1", this);
connect(button1,SIGNAL(clicked()), sfws, SLOT(receive(QString)));
connect(sfws, SIGNAL(forward(QString)), this,SLOT(backgroundTypeChoiceMade(QString)));
sfws = new SignalForwarderWithString("button2", this);
connect(button2,SIGNAL(clicked()), sfws, SLOT(receive(QString)));
connect(sfws, SIGNAL(forward(QString)), this,SLOT(backgroundTypeChoiceMade(QString)));
but QSignalMapper is just as easy...
QSignalMapper *mapper = new QSignalMapper(this);
connect(button1, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(button1, "button 1");
connect(button2, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(button2, "button 2");
// you might have to tweak the argument type for your slot...
connect(mapper, SIGNAL(mapped(const QString &), this, SLOT(backgroundTypeChoiceMade(QString)));