Connecting two windows
-
That's right :)
was just answering to the original question :
What I'm doing wrong here?
have a nice day
-
@russjohn834 Just a tip: to avoid circular dependencies use forward declarations:
// a.h class B; // This is forward declaration for class B, no need to include b.h here class A { private: B *b; }; // b.h #include "a.h" ...
Forward declarations work only for pointers - in the above example it would not work if b would not be a pointer.
-
@jsulm Thank you for your suggestion.
Just to further clarify myself the use of forward declaration:Two form classes
MainWindow
andStageOne
StageOne
needs to connect with a signal fromMainWindow
I did this in
StageOne
class MainWindow; // ---------> forward declaration for Mainwindow namespace Ui { class StageOne; } class StageOne : public QMainWindow { Q_OBJECT public: explicit StageOne(QString, QWidget *parent = nullptr); ~StageOne(); private: Ui::StageOne *ui; MainWindow *window; };
I'm trying to connect as follows in
StageOne
:connect(window,&MainWindow::patientIdChanged, ui->label, &QLabel::setText);
But this gives an error says:
stageone.cpp:12:21: error: incomplete type 'MainWindow' named in nested name specifier stageone.h:10:7: note: forward declaration of 'MainWindow'
in
mainwindow
, i did include#include "stageone.h"
what mistake I'm doing here?
Thank you
-
@russjohn834 You need to include mainwindow.h header in stageone.cpp
-
@jsulm if I include mainwindow.h header in stageone.cpp, I get follwoing error:
mainwindow.h:25: error: C2143: syntax error: missing ';' before '*' mainwindow.h:25: error: C4430: missing type specifier - int assumed. Note: C++ does not support default-int mainwindow.h:25: error: C2238: unexpected token(s) preceding ';'
Which points here:
#include <QMainWindow> #include "stagetwonew.h" #include "stageone.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); StageTwoNew *stagetwonew; StageOne *stageone; //--------------------> points here signals: void patientIdChanged(QString); private slots: void on_pushButton_New_clicked(); void on_pushButton_Open_clicked(); void parseDataEntry(const QString dataPath); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
-
@russjohn834 Are you sure you don't include mainwindow.h in stageone.h?
Please show both header files. -
I tried with without and with mainwindow.h in stageone.h. I'm a bit confused, you mentioned this earlier:
@jsulm said in Connecting two windows:@russjohn834 You need to include mainwindow.h header in stageone.cpp
-
here are two header files:
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QDebug> #include <QFile> #include <QDirIterator> #include <QXmlStreamReader> #include <QMessageBox> #include "stagetwonew.h" #include "stageone.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); StageTwoNew *stagetwonew; StageOne *stageone; signals: void patientIdChanged(QString); private slots: void on_pushButton_New_clicked(); void on_pushButton_Open_clicked(); void parseDataEntry(const QString dataPath); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
and
stageone.h
:#ifndef STAGEONE_H #define STAGEONE_H #include <QMainWindow> //#include "mainwindow.h" #include "stagetwonew.h" class MainWindow; namespace Ui { class StageOne; } class StageOne : public QMainWindow { Q_OBJECT public: explicit StageOne(QString, QWidget *parent = nullptr); ~StageOne(); private: Ui::StageOne *ui; MainWindow *window; }; #endif // STAGEONE_H
I do this at stageone:
StageOne::StageOne(QString someLabel, QWidget *parent) : QMainWindow(parent), ui(new Ui::StageOne) { ui->setupUi(this); // MainWindow *mainWindow= new MainWindow(this); connect(window,&MainWindow::patientIdChanged, ui->label, &QLabel::setText); // }
this gives an error says:
stageone.cpp:12:21: error: incomplete type 'MainWindow' named in nested name specifier stageone.h:10:7: note: forward declaration of 'MainWindow'
-
@russjohn834 said in Connecting two windows:
#include "stagetwonew.h"
Does this one include mainwindow.h?
"stageone.cpp:12:21: error: incomplete type 'MainWindow' named in nested name specifier" - yes, because you did not include mainwindow.h in stageone.cpp
You really messed up your includes... -
@jsulm I have a doubt
@jsulm said in Connecting two windows:
@russjohn834 Just a tip: to avoid circular dependencies use forward declarations:
// a.h class B; // This is forward declaration for class B, no need to include b.h here class A { private: B *b; }; // b.h #include "a.h" ...
in the above example, even if I forward declare class B , I may not able to use any methods in class B unless I include
b.h
?So I was thinking how this is useful in a case , for ex:
class B contains a signal which needs to be connected in class A?
-
Hi,
In that case, the real question is: do you really need these classes to know each other ?
-
@russjohn834 said in Connecting two windows:
I may not able to use any methods in class B unless I include b.h?
You can, in b.cpp if you include the header file there as I already said.
Forward declaration only tells the compiler that B is a class, nothing more. This information is enough to declare a pointer to B (as pointer have always same size). But as soon as you want to access members/methods of B you need to include the header file, then compiler knows exactly what B is and which members/methods it has. See https://pvigier.github.io/2018/02/09/dependency-graph.html
But as @SGaist said you should seriously rethink your design: are you sure both classes need to know each other? Usually it is enough that one class knows something about the other one. In Qt you can use signals/slots to implement loosely coupling.