same signal-slot connection in two windows
-
Hi All,
I have two windows (
QMainWindow), saySettingsandPatients.There is a signal - slot connection in the
Settingsas follows:connect(&api, SIGNAL(batteryEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandler(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));here
eventHandlercontrols an LED battery status buttonIn the
Settingswindow this works fine. Now I need to do the same thing onPatientswindow (controls an LED),Pateintsis constructed fromSettings. I trie doing the same connection (below) in thePatientswindow but that seems not working.connect(&api, SIGNAL(batteryEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandlerTwo(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));Any idea what am I doing wrong here?
-
Hi All,
I have two windows (
QMainWindow), saySettingsandPatients.There is a signal - slot connection in the
Settingsas follows:connect(&api, SIGNAL(batteryEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandler(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));here
eventHandlercontrols an LED battery status buttonIn the
Settingswindow this works fine. Now I need to do the same thing onPatientswindow (controls an LED),Pateintsis constructed fromSettings. I trie doing the same connection (below) in thePatientswindow but that seems not working.connect(&api, SIGNAL(batteryEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandlerTwo(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));Any idea what am I doing wrong here?
@russjohn834
Hi
Check if the connect return TRUE
Also, make sure none of the objects runs out of scope
I can see you use & on the API class so make sure its not a local variable.Also consider using the new connect syntax as that catches more errors
https://wiki.qt.io/New_Signal_Slot_SyntaxAlso, show the code for the settings things that don't work.
Classic errors include creating a new instance to connect instead on the one on screen or
using a local variable that won't live long enough to send any signals.
But it could also be something else so we need to see the full code for the creation and connection to have
a chance to say where it went wrong. -
Hi All,
I have two windows (
QMainWindow), saySettingsandPatients.There is a signal - slot connection in the
Settingsas follows:connect(&api, SIGNAL(batteryEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandler(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));here
eventHandlercontrols an LED battery status buttonIn the
Settingswindow this works fine. Now I need to do the same thing onPatientswindow (controls an LED),Pateintsis constructed fromSettings. I trie doing the same connection (below) in thePatientswindow but that seems not working.connect(&api, SIGNAL(batteryEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandlerTwo(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));Any idea what am I doing wrong here?
@russjohn834 I wonder if you need a different approach here.
Are those QMainWindows at the same level? I mean, are they created in some "higher level" container object?
If so, maybe you need to move the handling of the battery event and LED on/off task there. I'm thinking what will happen if you need to add 2 more windows, are you going to connect the api and LED handling in those new windows as well? and then you're asked to add 2 more windows... it seems not good for app maintenance... -
@mrjj @Pablo-J-Rogina Thanks.
just a quick question, how can I switch following into the new Signal-slot syntax?
connect(&api, SIGNAL(tetraGripEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandler(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));here
apiis global variable -
@mrjj @Pablo-J-Rogina Thanks.
just a quick question, how can I switch following into the new Signal-slot syntax?
connect(&api, SIGNAL(tetraGripEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandler(STIM_GUI_TOPIC_T , uint8_t , uint32_t )));here
apiis global variableHello!
The new
Signal-slotsyntax will be like this:connect(this, &Test::tetraGripEvent, this, &Test::eventHandler);Note: this is just a test example. Where the
Testis your current class and it emitting a signal and receiving it. Also, you can do it using lambda.connect(this, &Test::tetraGripEvent, [this](STIM_GUI_TOPIC_T a, uint8_t b, uint32_t c) { eventHandler(a, b, c); });You need to provide more info about the
apiglobal variable, where and how you have initialized it? -
@Cobra91151 Thank you.
I define the instance of my API class in the main as follows:
tetra_grip_api api; ------------>class instance int main(int argc, char *argv[]) { QApplication a(argc, argv); api.openSerialPort(); QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData())); Settings w(nullptr); w.show(); return a.exec(); }In this case, how do I switch the following expression into the new signal-slot syntax?
connect(&api, SIGNAL(tetraGripEvent(STIM_GUI_TOPIC_T, uint8_t, uint32_t )), this, SLOT(eventHandlerTwo(STIM_GUI_TOPIC_T , uint8_t , uint32_t ))); -
@jazzco2 Thanks a lot.
The new connect syntax seems ok. It did not complain about anything. But I'm not getting the expected output. Just to summarize.
I'm calling QMainWindow
PatientsfromSettings. In thePatientsconstructor, I did connect as follows:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);When I put a breakpoint in the connect statement, it did not went into the
eventHandlerTwoslot. which means something wrong in the way I did the connection.where
apiis global variable.eventHandlerTwois a public slot:void Patients::eventHandlerTwo( STIM_GUI_TOPIC_T topic, uint8_t reg, uint32_t value) { if (topic==TOPIC_STIMULATOR) { switch(reg) { case STIM_REG_BATTERY_CAPACITY_REMAINING: if(value<86) ui->qLed_p2->setOnColor(QLed::Red); else ui->qLed_p2->setOnColor(QLed::Green); ui->qLed_p2->setValue(true); break; } } ui->label_batteryVal->setText(QString::number(value)); }Patientsbeing called fromSettingsas follows:void Settings::on_pushButton_patients_clicked() { hide(); stagetwo = new Patients(this); stagetwo -> show(); }Any thoughts?
-
So where do you call your connect() statement?
-
@jazzco2 Thanks a lot.
The new connect syntax seems ok. It did not complain about anything. But I'm not getting the expected output. Just to summarize.
I'm calling QMainWindow
PatientsfromSettings. In thePatientsconstructor, I did connect as follows:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);When I put a breakpoint in the connect statement, it did not went into the
eventHandlerTwoslot. which means something wrong in the way I did the connection.where
apiis global variable.eventHandlerTwois a public slot:void Patients::eventHandlerTwo( STIM_GUI_TOPIC_T topic, uint8_t reg, uint32_t value) { if (topic==TOPIC_STIMULATOR) { switch(reg) { case STIM_REG_BATTERY_CAPACITY_REMAINING: if(value<86) ui->qLed_p2->setOnColor(QLed::Red); else ui->qLed_p2->setOnColor(QLed::Green); ui->qLed_p2->setValue(true); break; } } ui->label_batteryVal->setText(QString::number(value)); }Patientsbeing called fromSettingsas follows:void Settings::on_pushButton_patients_clicked() { hide(); stagetwo = new Patients(this); stagetwo -> show(); }Any thoughts?
@russjohn834 said in same signal-slot connection in two windows:
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);When I put a breakpoint in the
connectstatement, it did not went into theeventHandlerTwoslot. which means something wrong in the way I did connection.What do you mean? When the
connectstatement is executed it will not cause any entry intoPatients::eventHandlerTwo, that only comes when the signal is lateremitted. -
Connect is called as in the following:
Patients::Patients(QWidget *parent) : QMainWindow(parent), ui(new Ui::Patients) { ui->setupUi(this); this->setStyleSheet("background-color: white;"); this->setFixedSize(this->width(),this->height()); connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo); //--->connect is called here // Setup table ui->tableWidget->setColumnCount(5); ui->tableWidget->setHorizontalHeaderLabels(QStringList{"Patient ID","Name", "Surname", "LastSession", "Note"}); ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); QString path = QCoreApplication::applicationDirPath()+"/data/"; QStringList qdiFilter("*.xml"); QDirIterator qdi( path, qdiFilter, QDir::Files); while (qdi.hasNext()) { parseDataEntry(qdi.next()); } } -
@russjohn834 said in same signal-slot connection in two windows:
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);When I put a breakpoint in the
connectstatement, it did not went into theeventHandlerTwoslot. which means something wrong in the way I did connection.What do you mean? When the
connectstatement is executed it will not cause any entry intoPatients::eventHandlerTwo, that only comes when the signal is lateremitted.I'm connecting with the same signal in the previous window , so do I need to
disconnectthat and connection to use the same signal in with a new slot?Basically in
Settingswindow this works:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler); //--> slot is eventHandlerBut in
Patientsthis is not working:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);//--->Slot is eventHandlerTwo -
I'm connecting with the same signal in the previous window , so do I need to
disconnectthat and connection to use the same signal in with a new slot?Basically in
Settingswindow this works:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler); //--> slot is eventHandlerBut in
Patientsthis is not working:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);//--->Slot is eventHandlerTwo@russjohn834
So I now take it you mean you find the slot does not get entered, not the the connect fails?No, you do not have to disconnect, a signal may have any number of slots attached. Though if a previously-attached slot does not return, or misbehaves like if the slot instance is no longer around, it is possible the second slot might not get called.
So if debugging what is going you might be advised to temporarily not connect the
Settingsslot, just thePatientsslot and concentrate on sorting that out. It is not possible to say from what you have posted why one slot works and the other does not. -
@JonB Thank you. I tried to connect only the
Patientsslot but cant see where I'm wrong..Patientswindow is opened fromSettingsas given below:void Settings::on_pushButton_patients_clicked() { hide(); stagetwo = new Patients(this); stagetwo -> show(); }Where
stagetwois publicpublic: Settings(QString,QWidget *parent = nullptr); ~Settings(); Patients *stagetwo;Anything wrong I'm doing here!?
-
Hi all,
I just noticed this thing if I call both my
SettingsandPatientsfrom my main the connection is successful (see below)#include <QApplication> tetra_grip_api api; int main(int argc, char *argv[]) { QApplication a(argc, argv); api.openSerialPort(); QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData())); QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handling Settings w(nullptr); w.show(); Patients v(nullptr); //---------> this makes connection successfull v.show(); return a.exec(); }but instead, if I call
PatientsfromSettingseven though the connection is successful im not getting the expected output.My signal source
apiis a global variable which is initialized in the main as shown above.
So constructing both classes in the main makes connection ok and I'm gettting expected output. But if I call one window from other makes connection true but my slot is not being called at all.What is the reason for this?
-
Hi all,
I just noticed this thing if I call both my
SettingsandPatientsfrom my main the connection is successful (see below)#include <QApplication> tetra_grip_api api; int main(int argc, char *argv[]) { QApplication a(argc, argv); api.openSerialPort(); QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData())); QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handling Settings w(nullptr); w.show(); Patients v(nullptr); //---------> this makes connection successfull v.show(); return a.exec(); }but instead, if I call
PatientsfromSettingseven though the connection is successful im not getting the expected output.My signal source
apiis a global variable which is initialized in the main as shown above.
So constructing both classes in the main makes connection ok and I'm gettting expected output. But if I call one window from other makes connection true but my slot is not being called at all.What is the reason for this?
@russjohn834
If you're asking me to guess, show how you gain access totetra_grip_api api;fromSettings/Patients? In these cases where do you do theconnect()s from? And, how do you know yourconnect()s are successful? -
Hi,
@russjohn834 said in same signal-slot connection in two windows:
QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData()));
QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handlingSince serial is internal to
apiwhy don't you connect it in the constructor of your tetra_grip_api class ? -
@russjohn834
If you're asking me to guess, show how you gain access totetra_grip_api api;fromSettings/Patients? In these cases where do you do theconnect()s from? And, how do you know yourconnect()s are successful?This is how I make the connection in
Settings.Settings::Settings(QString patientLabel, QWidget *parent) : QMainWindow(parent) , ui(new Ui::Settings) { ui->setupUi(this); connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler); }Connection is successfull (
qDebug()<<connect(....)gives TRUE) also the aQLabeland an LED in theeventHandlerslot works perfectly.In the same way I try to connect in the
Patients:Patients::Patients(QWidget *parent) : QMainWindow(parent) , ui(new Ui::Patients) { ui->setupUi(this); connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo); }here connection is successfull (
qDebug()<<connect(....)gives TRUE) but the aQLabeland an LED in theeventHandlerTwoare not working. -
This is how I make the connection in
Settings.Settings::Settings(QString patientLabel, QWidget *parent) : QMainWindow(parent) , ui(new Ui::Settings) { ui->setupUi(this); connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler); }Connection is successfull (
qDebug()<<connect(....)gives TRUE) also the aQLabeland an LED in theeventHandlerslot works perfectly.In the same way I try to connect in the
Patients:Patients::Patients(QWidget *parent) : QMainWindow(parent) , ui(new Ui::Patients) { ui->setupUi(this); connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo); }here connection is successfull (
qDebug()<<connect(....)gives TRUE) but the aQLabeland an LED in theeventHandlerTwoare not working.@russjohn834
How do I know&apirefers to the same, global, initializedapiinstance in both cases?
And I see nothing in code about anyQLabelin either case, not mentioned by you before...
You have to supply the necessary/relevant code if you want people to help.
Use a debugger to make sure whether slots are being hit. -
I thought
apishould be known and accessible to all classes if intialized as global in themain.cpp#include <QApplication> tetra_grip_api api; //-------------> api instance int main(int argc, char *argv[]) { QApplication a(argc, argv); api.openSerialPort(); QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData())); QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handling Settings w(nullptr); w.show(); return a.exec(); }Correct me if I'm wrong.