signal/slot not working
-
Hi all -
I feel like a Qt rookie again; I remember asking questions like this 10 years ago.
I'll let the code do the talking:
class WifiSetup : public QDialog { Q_OBJECT ... void onMsgReceived(Message *msg); void onAckReceived(Message *msg); } WifiSetup::WifiSetup() { ... QObject::connect(m_worker, &Worker::newSerialData, this, &WifiSetup::onMsgReceived); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived); } void WifiSetup::onMsgReceived(Message *msg) {...} void WifiSetup::onAckReceived(Message *msg) {...} void Worker::processSerial(QByteArray buff) { mt = m_msg.getType(); switch (mt) { case MSG_DISCOVERY_ACK: emit newSerialData(&m_msg); break; case MSG_WIFI_SETUP_ACK: emit wifiSetupAckReceived(&m_msg); break; ... }When mt == MSG_DISCOVERY_ACK, the signal and slot work correctly.
When mt == MSG_WIFI_SETUP_ACK, the signal is called, but the slot is never reached.I've run clean, qmake and rebuild...same behavior. I'm sure I'm overlooking something painfully obvious, but I sure don't see what.
Thanks...
-
Not the answer you're expecting, but: I don't see anything painfully obvious in here.
Both
connect()statements are called after the worker is moved to thread, right? -
@mzimmers said in signal/slot not working:
WifiSetup
Is that class type registered? ie
qRegisterMetaType<WifiSetup>("WifiSetup");It needs registering before using signals and slots.
https://doc.qt.io/qt-5/qtcore-threads-queuedcustomtype-example.html
-
@mzimmers said in signal/slot not working:
WifiSetup
Is that class type registered? ie
qRegisterMetaType<WifiSetup>("WifiSetup");It needs registering before using signals and slots.
https://doc.qt.io/qt-5/qtcore-threads-queuedcustomtype-example.html
@6thC said in signal/slot not working:
@mzimmers said in signal/slot not working:
WifiSetup
Is that class type registered? ie
qRegisterMetaType<WifiSetup>("WifiSetup");It needs registering before using signals and slots.
https://doc.qt.io/qt-5/qtcore-threads-queuedcustomtype-example.html
This is not true. Signal/slot arguments need to be registered, not the worker object.
-
Not the answer you're expecting, but: I don't see anything painfully obvious in here.
Both
connect()statements are called after the worker is moved to thread, right? -
@sierdzio yes, the signals are called after the worker is moved.
(how did you know worker was in another thread?)
@mzimmers said in signal/slot not working:
@sierdzio yes, the signals are called after the worker is moved.
(how did you know worker was in another thread?)
It's common to call objects working in other threads "workers" :-)
-
@mzimmers said in signal/slot not working:
@sierdzio yes, the signals are called after the worker is moved.
(how did you know worker was in another thread?)
It's common to call objects working in other threads "workers" :-)
-
Just a guess, but maybe it's a timing problem, if the MSG_WIFI_SETUP_ACK message arrives in the Worker before
QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived);has been run...@hskoglund thanks for the suggestion, but that's definitely not the case. The connect statement is run in the c'tor of the QWidget, and the message only comes after the user presses a button, a message is sent out to the remote device and a response is read.
-
Hi all -
I feel like a Qt rookie again; I remember asking questions like this 10 years ago.
I'll let the code do the talking:
class WifiSetup : public QDialog { Q_OBJECT ... void onMsgReceived(Message *msg); void onAckReceived(Message *msg); } WifiSetup::WifiSetup() { ... QObject::connect(m_worker, &Worker::newSerialData, this, &WifiSetup::onMsgReceived); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived); } void WifiSetup::onMsgReceived(Message *msg) {...} void WifiSetup::onAckReceived(Message *msg) {...} void Worker::processSerial(QByteArray buff) { mt = m_msg.getType(); switch (mt) { case MSG_DISCOVERY_ACK: emit newSerialData(&m_msg); break; case MSG_WIFI_SETUP_ACK: emit wifiSetupAckReceived(&m_msg); break; ... }When mt == MSG_DISCOVERY_ACK, the signal and slot work correctly.
When mt == MSG_WIFI_SETUP_ACK, the signal is called, but the slot is never reached.I've run clean, qmake and rebuild...same behavior. I'm sure I'm overlooking something painfully obvious, but I sure don't see what.
Thanks...
@mzimmers said in signal/slot not working:
When mt == MSG_WIFI_SETUP_ACK, the signal is called, but the slot is never reached.
How do you know it is called? Is the code containing the
emityours/debug-breakpointable by you?Is
m_workeranother thread?Add a brand new pair of slots, which do nothing, and attach them too to the signals. Preferably first. Do they behave the same?
-
@mzimmers said in signal/slot not working:
When mt == MSG_WIFI_SETUP_ACK, the signal is called, but the slot is never reached.
How do you know it is called? Is the code containing the
emityours/debug-breakpointable by you?Is
m_workeranother thread?Add a brand new pair of slots, which do nothing, and attach them too to the signals. Preferably first. Do they behave the same?
@JonB said in signal/slot not working:
How do you know it is called? Is the code containing the emit yours/debug-breakpointable by you?
Is m_worker another thread?Yes, and yes. The emit is in my first post.
Add a brand new pair of slots, which do nothing, and attach them too to the signals. Preferably first. Do they behave the same?
QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::testSlot1); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::testSlot2); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived); void WifiSetup::testSlot1() { qDebug() << "testSlot1 reached."; } void WifiSetup::testSlot2() { qDebug() << "testSlot2 reached."; }I put breakpoints on all three slots...none are hit. And it's not some debugger error; no action by the slot(s) is taken.
-
@JonB said in signal/slot not working:
How do you know it is called? Is the code containing the emit yours/debug-breakpointable by you?
Is m_worker another thread?Yes, and yes. The emit is in my first post.
Add a brand new pair of slots, which do nothing, and attach them too to the signals. Preferably first. Do they behave the same?
QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::testSlot1); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::testSlot2); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived); void WifiSetup::testSlot1() { qDebug() << "testSlot1 reached."; } void WifiSetup::testSlot2() { qDebug() << "testSlot2 reached."; }I put breakpoints on all three slots...none are hit. And it's not some debugger error; no action by the slot(s) is taken.
@mzimmers
Earlier you said:When mt == MSG_DISCOVERY_ACK, the signal and slot work correctly.
When mt == MSG_WIFI_SETUP_ACK, the signal is called, but the slot is never reached.
Good grief! I meant, a new pair, one on
newSerialData, one onwifiSetupAckReceived. Not 3 on one and one on the other! Wanted to check the two signals each behaved the same as you reported (one good, one bad) on new slots.Dunno, bet it's a thread thing :)
-
@mzimmers
Earlier you said:When mt == MSG_DISCOVERY_ACK, the signal and slot work correctly.
When mt == MSG_WIFI_SETUP_ACK, the signal is called, but the slot is never reached.
Good grief! I meant, a new pair, one on
newSerialData, one onwifiSetupAckReceived. Not 3 on one and one on the other! Wanted to check the two signals each behaved the same as you reported (one good, one bad) on new slots.Dunno, bet it's a thread thing :)
@JonB said in signal/slot not working:
Good grief! I meant, a new pair, one on
newSerialData, one onwifiSetupAckReceived. Not 3 on one and one on the other! Wanted to check the two signals each behaved the same as you reported (one good, one bad) on new slots.Sigh...my brain's still in low gear.
QObject::connect(m_worker, &Worker::newSerialData, this, &WifiSetup::testSlot1); QObject::connect(m_worker, &Worker::newSerialData, this, &WifiSetup::onMsgReceived); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::testSlot2); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived);Both slots for newSerialData get hit; neither of the ones for wifiSetupAckReceived get hit.
Dunno, bet it's a thread thing :)
What's confounding about this is that one works, and the other doesn't. Seemingly identical.
-
@JonB said in signal/slot not working:
Good grief! I meant, a new pair, one on
newSerialData, one onwifiSetupAckReceived. Not 3 on one and one on the other! Wanted to check the two signals each behaved the same as you reported (one good, one bad) on new slots.Sigh...my brain's still in low gear.
QObject::connect(m_worker, &Worker::newSerialData, this, &WifiSetup::testSlot1); QObject::connect(m_worker, &Worker::newSerialData, this, &WifiSetup::onMsgReceived); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::testSlot2); QObject::connect(m_worker, &Worker::wifiSetupAckReceived, this, &WifiSetup::onAckReceived);Both slots for newSerialData get hit; neither of the ones for wifiSetupAckReceived get hit.
Dunno, bet it's a thread thing :)
What's confounding about this is that one works, and the other doesn't. Seemingly identical.
-
@mzimmers
Send me $5 if it turns out you're doing something else in your code causing this behaviour.... -
Hi,
@mzimmers said in signal/slot not working:
mt = m_msg.getType();
switch (mt)When is m_msg updated ? You could be processing the same value twice.
-
void Worker::processSerial(QByteArray buff) { MsgType mt; string s; s.assign(buff); m_msg.decodeXml(s); mt = m_msg.getType(); switch (mt) { case MSG_DISCOVERY_ACK: emit newSerialData(&m_msg); break; case MSG_WIFI_SETUP_ACK: emit wifiSetupAckReceived(&m_msg); break; ...Besides, the signal is being emitted (at least according to the debugger).
-
Insert a qDebug() before the
emitto be 100% sure.One more idea... this method isn't called once, is it? Because if it is called once, and your have a
break;in yourswitchthen only the first ack will triggerMSG_DISCOVERY_ACK, then it will break and never bother to check ifMSG_WIFI_SETUP_ACKis satisfied or not. -
Let's be 100% clear for everyone: because of your separate threads, these are queued-connection signals, right? So the slots won't be called during the
emits, only later on, and we're all clear about this, right?@sierdzio said in signal/slot not working:
Insert a qDebug() before the emit to be 100% sure.
Damn right, I'd have expected you to do this to make sure already!