Solved Connecting 2 different classes together
-
Also I forgot to mention that, there is also a connect and declaration in the usb.cpp file like this:
protocolFormInstance = new protocolForm(); connect(this,SIGNAL(sendCOMPort(QString)),protocolFormInstance , SLOT(receiveCOMPort(QString)));
And the header file of protocolForm there is this line:
USB* USBInstance;
Now when I commented out these all lines from USB header and cpp file. The connect and declaration line the protocolform.cpp file do not crash anymore. So I believe I should transfer the connect line I commented out from the USB.cpp file to protocolform.cpp.
So at the end protocol.cpp file should include both of the connects. However, when I tried that I cannot use the sendComPort() signal which is declared in the USB header. Maybe I should make USB class a child class of the protocolform class. -
@GunkutA
First, not surprisingly, I now see you have changed what yourconnect()
looks like for the slot side. Using theSLOT()
macro hides incorrect parameter passing. Your new-style connect really should look like:connect(this, &ThisClassName::sendCOMPort, protocolFormInstance , &ProtocolFormClassName::receiveCOMPort);
But looking at this, it seems likely it's the wrong way round. If
this
isUSB
, and that is the signaller, then the above should be done within theProtocolForm
slot class:connect(USBinstance, &USB::sendCOMPort, this, &ProtocolFormClassName::receiveCOMPort);
Maybe I should make USB class a child class of the protocolform class.
Absolutely not!
So at the end protocol.cpp file should include both of the connects.
What both
connect()
s? You have shown oneconnect()
. What is the secondconnect()
? I want to see both theconnect()
s you have. -
@JonB Okay I tried all possibilities and found what causes the crash ( I hope). So when I declare USB in protocolform and protocol form in USB.cpp , at the same time program gets crashed :
USB.h
private: protocolForm* protocolFormInstance;
USB.ccp
protocolFormInstance = new protocolForm;
Protocolform.h
private: Ui::protocolForm *ui; USB* USBInstance;
Protocolform.cpp
USBInstance = new USB;
Eventough all the connect lines are commented out, that declarations cause crash I believe. ( Btw I can send all the headers and cpp files in here if it wouldn't be too long.)
-
It matters where these instantiation lines are. If you have both
new
s in constructors then it will surely crash (infinite loop!). If you separate them so that one object is create later, it will work. -
@GunkutA
Protocolform
is some kind of UI widget/form, right? While, at a guess,USB
is not a GUI element?Then I get why
Protocolform
needs to know aboutUSB
, to connect a slot to its signal(s). That sounds OK.But, if that is so, why does
USB
class need to know anything aboutProtocolform
UI class?? Why doesUSB.h/cpp
need those references toprotocolForm
? It sounds like it should not, and then you would get of your circular dependency.... -
Because I was planning to know button presses from GUI ( which is protocolForm) in the USB class. Then I would connect to the USB port.
-
@sierdzio I believe they are in constructors :(
Complete USB.cpp code ( as an example) looks like this:#include "usb.h" #include <QtSerialPort> #include <QSerialPortInfo> #include <QtSerialPort/QSerialPortInfo> #include <QtSerialPort/QSerialPortInfo> #include <QSerialPort> #include "mainwindow.h" #include "protocolform.h" #include <QDebug> USB::USB(QObject *parent) : QObject(parent) { QSerialPort *serial; timer = new QTimer(this); serial = new QSerialPort(this); connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeoutSLOT())); timer->start(1000); protocolFormInstance = new protocolForm; // protocolFormInstance = new protocolForm(); connect(this,&USB::sendCOMPort(QString),protocolFormInstance , &protocolForm::receiveCOMPort(QString)); } void USB::timerTimeoutSLOT() { qDebug()<<"Timed out..."; emit sendCOMPort("begin"); // Q_FOREACH(QSerialPortInfo port, QSerialPortInfo::availablePorts()) { // emit sendCOMPort(port.portName()); // } } void USB::receiveChosenComPort(const QString &ChosenComPort) { }
and the header of the USB:
#ifndef USB_H #define USB_H #include "protocolform.h" #include <QObject> class USB : public QObject { Q_OBJECT public: explicit USB(QObject *parent = nullptr); QTimer *timer; public slots: void timerTimeoutSLOT(); void receiveChosenComPort(const QString &ChosenComPort); signals: void sendCOMPort(const QString &COMPort); private: //protocolForm* protocolFormInstance; }; #endif // USB_H
-
@GunkutA said in Connecting 2 different classes together:
Because I was planning to know button presses from GUI ( which is protocolForm) in the USB class. Then I would connect to the USB port.
That is exactly what signals and slots are for. Your
USB
class does not need to know anything about any UI. It will simply have some slot, like for exampleonButtonPressed()
orsomethingHappened()
and it will respond to such event (signal). It does not need to know any more details. And if it does, then you can send the necessary information as argument in your signal and slot.Then, if
USB
needs to inform the UI about something, it emits a signal as well. -
protocolFormInstance = new protocolForm; // protocolFormInstance = new protocolForm(); connect(this,&USB::sendCOMPort(QString),protocolFormInstance , &protocolForm::receiveCOMPort(QString));
This is all in the wrong place/wrong way round. The
USB
class handles serial/USB activity. It should know nothing aboutprotocolForm
, it should notnew
it. As I wrote above, theconnect()
belongs in theprotocolForm
class.You need to stop typing/commenting out stuff and take time to understand the necessary approach correctly. I leave this to you/ @sierdzio now, as I have tried to explain and give examples of all I can....
-
@sierdzio Well the thing is, it needs to know the selected COM Port from the GUI. So there will be 3 COM Ports for example and when the button pressed, USB class will know the which COM Port is selected and then it will connect to it. So I believe I need to send COM Port info from GUI to USB class.
-
@GunkutA said in Connecting 2 different classes together:
@sierdzio Well the thing is, it needs to know the selected COM Port from the GUI. So there will be 3 COM Ports for example and when the button pressed, USB class will know the which COM Port is selected and then it will connect to it. So I believe I need to send COM Port info from GUI to USB class.
Yes, do it by argument. USB class does not need to know anything more. So, a minimal example:
// UI UiClass : public QWidget { Q_OBJECT USB *usb = nullptr; signals: void openPort(const int port) const; public: UiClass(QWidget *parent = nullptr) : public QWidget(parent) { usb = new USB; connect(this, &UiClass::openPort, usb, &USB::onOpenPort); } }; // USB class class USB : public QObject { Q_OBJECT public slots: void onOpenPort(const int port) { // Do something with the port } };
-
@sierdzio I got it, thank you for all the effort.