PDA

View Full Version : QSignalMapper with one object being a thread (no visual object)



PeterVE
25th July 2016, 23:09
Hello,

I have a Dialog Box with a background thread doing work for it. The provided example from Qt used Signals and Slots and did not use QSignalMapper at all which is surprising. Well, upgrading to 5.7, this no longer works. They must have closed a bug or two which is indirectly a good thing for Qt. I now need to make this work the right way. Here's parts of it...



class MyDialog : public QDialog
{
Q_OBJECT
...
public slots:
void showResponse ( const QString &stringResponse );
void processError ( const QString &stringError );
void processTimeout ( const QString &stringTimeout );
...
}

class MyThread : public QThread
{
Q_OBJECT
...
signals:
void response ( const QString & );
void error ( const QString & );
void timeout ( const QString & );
...
}

The direction of communication is child to parent and is thus a great reason to use signals and slots. But how do I set this up?

MyThread::MyDialog ( QQDialog* parent ) <--should i do this in MyThread or MyDialog?
: ...
{
...
m_signalMapper = new QSignalMapper (); // parent or this?
connect ( &m_threadATMega328p_RS232, SIGNAL ( response ( QString ) ), m_signalMapper, SLOT ( map () ) );
m_signalMapper->setMapping ( this, 0 ); // 0 is an ID but how do you reference 0 or 1 or 2? How do you map this to that?
//connect ( m_signalMapper, SIGNAL ( mapped ( QString ) ), this, SIGNAL ( response ( const QString & ) ) );
connect ( m_signalMapper, SIGNAL ( mapped ( QString ) ), this, SLOT ( showResponse ( QString ) ) );
...
}


What I need to do is have three SIGNAL functions in the thread that communicate with three SLOTS in the dialog box. So the setMapping call is important and I am unsure how to make this work with three different and dynamic QStrings. I saw examples but none with threads and surely none with one thread and three signals/slots. I read the help page but it talks about objects that have a function that gives dynamic text. This is not like that as I do have dynamic text as input, not that is callable.

Thanks for any direction. Have a great day.

Cheers,
Pete

anda_skoa
26th July 2016, 10:31
You just connect the thread's signal to the dialog's slots.

I guess you have code like this somewhere in your dialog



MyThread* thread = new MyThread(this);

so you just add


connect(thread, SIGNAL(response(QString)), this, SLOT(showResponse(QString)));

and so on.

Not sure why you would want to use a signal mapper and lose the signal arguments. Discarding the signal arguments can also be done in a normal connection.

Cheers,
_

PeterVE
26th July 2016, 14:44
Thank you. I did exactly that and it worked. What I had used from a Qt example was working until the upgrade. I tried to find examples online using arguments and they stated to use the signal mapper. But your suggestion is what was originally intended and does work. So thank you and have a great day!

anda_skoa
26th July 2016, 15:37
The signal mapper use case is if you have multiple signal sources without arguments and you want a single slot being called with arguments depending on the signal source.

E.g. a set of buttons and having the slot called with a numerical value or string depending on which button was clicked.

Cheers,
_