same signal-slot connection in two windows
-
@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
connect
statement, it did not went into theeventHandlerTwo
slot. which means something wrong in the way I did connection.What do you mean? When the
connect
statement is executed it will not cause any entry intoPatients::eventHandlerTwo
, that only comes when the signal is lateremit
ted. -
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()); } }
-
I'm connecting with the same signal in the previous window , so do I need to
disconnect
that and connection to use the same signal in with a new slot?Basically in
Settings
window this works:connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler); //--> slot is eventHandler
But in
Patients
this 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
Settings
slot, just thePatients
slot 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
Patients
slot but cant see where I'm wrong..Patients
window is opened fromSettings
as given below:void Settings::on_pushButton_patients_clicked() { hide(); stagetwo = new Patients(this); stagetwo -> show(); }
Where
stagetwo
is 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
Settings
andPatients
from 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
Patients
fromSettings
even though the connection is successful im not getting the expected output.My signal source
api
is 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
api
why don't you connect it in the constructor of your tetra_grip_api class ? -
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 aQLabel
and an LED in theeventHandler
slot 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 aQLabel
and an LED in theeventHandlerTwo
are not working. -
@russjohn834
How do I know&api
refers to the same, global, initializedapi
instance in both cases?
And I see nothing in code about anyQLabel
in 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
api
should 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
&Patients
classes are defined in a different source module frommain.cpp
, right? So how do they gain access to reference theapi
symbol 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 makingapi
instance as global inmain.cpp
. That might be the issue. But dont know how to proceed. How do I makePatients
classes know about globalapi
instance? -
@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
Patients
is done before the signaltetra_grip_api::tetraGripEvent
is emitted? SomeqDebug
s around connection, in the very first line ofPatients::eventHandlerTwo
and in the deconstructor ofPatients
should help to prove that. -
@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
/Patients
modules/.cpp
source files which contain the lineconnect(&api, ...
, whenapi
is 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
&api
in your connect statements in bothSettings
andPatients
and press F2 - where does it lead you to? -
From both
Settings
andPatients
,&api
leads 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.