same signal-slot connection in two windows
-
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.
-
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.
@russjohn834
YourSettings&Patientsclasses are defined in a different source module frommain.cpp, right? So how do they gain access to reference theapisymbol in order to compile?connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);I am having to tease out each bit of relevant information, one at a time....
-
@JonB
Correct. I actually did not do anything other that makingapiinstance as global inmain.cpp. That might be the issue. But dont know how to proceed. How do I makePatientsclasses know about globalapiinstance? -
@JonB
Correct. I actually did not do anything other that makingapiinstance as global inmain.cpp. That might be the issue. But dont know how to proceed. How do I makePatientsclasses know about globalapiinstance?@russjohn834 You should avoid global variables as much as possible.
Just pass the pointer to api to Settings & Patients constructors... -
Did you ensure that the connection in
Patientsis done before the signaltetra_grip_api::tetraGripEventis emitted? SomeqDebugs around connection, in the very first line ofPatients::eventHandlerTwoand in the deconstructor ofPatientsshould help to prove that. -
@JonB
Correct. I actually did not do anything other that makingapiinstance as global inmain.cpp. That might be the issue. But dont know how to proceed. How do I makePatientsclasses know about globalapiinstance?@russjohn834 said in same signal-slot connection in two windows:
@JonB
Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?I truly, truly do not understand. You said your program runs but does/does not behave properly in the cases you mentioned. I asked how you can even compile your
Settings/Patientsmodules/.cppsource files which contain the lineconnect(&api, ..., whenapiis defined inmain.cpp? From what you have said/shown they should error at compile-time with a "No such variable:api" message. So I will leave others to help, who obviously understand your source code better than I. -
@russjohn834 said in same signal-slot connection in two windows:
@JonB
Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?I truly, truly do not understand. You said your program runs but does/does not behave properly in the cases you mentioned. I asked how you can even compile your
Settings/Patientsmodules/.cppsource files which contain the lineconnect(&api, ..., whenapiis defined inmain.cpp? From what you have said/shown they should error at compile-time with a "No such variable:api" message. So I will leave others to help, who obviously understand your source code better than I. -
@russjohn834 If you are using QtCreator: When you go on the
&apiin your connect statements in bothSettingsandPatientsand press F2 - where does it lead you to? -
From both
SettingsandPatients,&apileads me here:#ifndef TETRA_GRIP_API_H #define TETRA_GRIP_API_H #include <QObject> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <QLabel> #include <QMessageBox> #include <QTimer> #define _CRT_SECURE_NO_DEPRECATE class tetra_grip_api : public QObject { Q_OBJECT public: explicit tetra_grip_api(QObject *parent = nullptr); #define MAX_CONFIG_FILE_LENGTH (10000) void static send_config_file(QByteArray config, bool nonvolatile); void static send_long_register(uint8_t, uint32_t, uint8_t *); void static stimulation_set_current(unsigned int, unsigned int); QSerialPort *serial = nullptr; QTimer autoConnectionTimer; bool tryToAutoconnect; signals: void tetraGripEvent(STIM_GUI_TOPIC_T topic, uint8_t reg, uint32_t value); public slots: void openSerialPort(); void closeSerialPort(); void readData(); private slots: void ErrorHandler(QSerialPort::SerialPortError error); private: QString comPortName; }; extern tetra_grip_api api; //----------> it leads me here #endif // TETRA_GRIP_API_H -
From both
SettingsandPatients,&apileads me here:#ifndef TETRA_GRIP_API_H #define TETRA_GRIP_API_H #include <QObject> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <QLabel> #include <QMessageBox> #include <QTimer> #define _CRT_SECURE_NO_DEPRECATE class tetra_grip_api : public QObject { Q_OBJECT public: explicit tetra_grip_api(QObject *parent = nullptr); #define MAX_CONFIG_FILE_LENGTH (10000) void static send_config_file(QByteArray config, bool nonvolatile); void static send_long_register(uint8_t, uint32_t, uint8_t *); void static stimulation_set_current(unsigned int, unsigned int); QSerialPort *serial = nullptr; QTimer autoConnectionTimer; bool tryToAutoconnect; signals: void tetraGripEvent(STIM_GUI_TOPIC_T topic, uint8_t reg, uint32_t value); public slots: void openSerialPort(); void closeSerialPort(); void readData(); private slots: void ErrorHandler(QSerialPort::SerialPortError error); private: QString comPortName; }; extern tetra_grip_api api; //----------> it leads me here #endif // TETRA_GRIP_API_H@russjohn834 said in same signal-slot connection in two windows:
extern tetra_grip_api api;
You really should not do it like this. Pass pointer to the constructors of the classes which need it.
-
@JonB Yes, that's interesting. You can't include
main.cppinSettingsor inPatients. Somain.cpps linetetra_grip_api api; //-------------> api instanceisn't visible anywhere!
@jazzco2 said in same signal-slot connection in two windows:
@JonB Yes, that's interesting. You can't include main.cpp in Settings or in Patients.
No, but you might be including
main.h, and maybe you haveextern tetra_grip_api api;there, that's the sort of thing I was trying to understand. Which finally you have shown is actually intetra_grip_api.h, which I guess you are including into each of them?For the line there
extern tetra_grip_api api;does the docs for tetra_grip_api say you are responsible for defining
tetra_grip_api api;yourself like you have done inmain.cpp, or does it say they (the library) are defining that global instance and you are supposed to use their instance? -
@russjohn834 Yes, pass the pointer - and then your api can be a local variable in main. No need to define it outside as main lives as long as the application is running.
-
Could you give me an example to show how do I pass a pointer to the constructor of the classes? for ex. if I need to use it in in
SettingsandPatientsclasses ? -
Could you give me an example to show how do I pass a pointer to the constructor of the classes? for ex. if I need to use it in in
SettingsandPatientsclasses ?@russjohn834 said in same signal-slot connection in two windows:
Could you give me an example to show how do I pass a pointer to the constructor of the classes?
Well
tetra_grip_api api; Settings settings(&api);Of cource you have to change the constructor, but this is C++ basic stuff.
-
@jazzco2 said in same signal-slot connection in two windows:
@JonB Yes, that's interesting. You can't include main.cpp in Settings or in Patients.
No, but you might be including
main.h, and maybe you haveextern tetra_grip_api api;there, that's the sort of thing I was trying to understand. Which finally you have shown is actually intetra_grip_api.h, which I guess you are including into each of them?For the line there
extern tetra_grip_api api;does the docs for tetra_grip_api say you are responsible for defining
tetra_grip_api api;yourself like you have done inmain.cpp, or does it say they (the library) are defining that global instance and you are supposed to use their instance?it did not mention anything like that. My primary requirement is to use
tetra_grip_api(which is a class containing all serial communication objects) instance in every form class. That's why I made it global, but now I realize it's not a good way of programming!