MainWindow’ does not name a type;
-
I am trying to declare MainWindow as a class variable and getting this error.
/media/qe/RAID_CAT_MD0/QT_PROGRAMS/JULY_30/30_work_1/CAT/mdi/form_setup.h:53: error: ‘MainWindow’ does not name a type; did you mean ‘QWindow’? In file included from ../JULY_30/30_work_1/CAT/mdi/mainwindow.h:65, from moc_mainwindow.cpp:10: ../JULY_30/30_work_1/CAT/mdi/form_setup.h:53:5: error: ‘MainWindow’ does not name a type; did you mean ‘QWindow’? 53 | MainWindow *form; | ^~~~~~~~~~ | QWindow I have no issue when used as "local" in constructor - when it is NOT declared as class variable MainWindow *form = qobject_cast< MainWindow *>(parent);
However I need to be able for other methods to access the "form".
-
../JULY_30/30_work_1/CAT/mdi/form_setup.h:53:5: error: ‘MainWindow’ does not name a type;
If you want to use
MainWindow
inform_setup.h
you need to includemainwindow.h
there, but judging from the other error you seem to already have the reverse - you includeform_setup.h
inmainwindow.h
, so this can't work. Which leads me neatly to the other thing:I need to be able for other methods to access the "form".
That's usually a clear sign of badly designed app structure. The main window should usually be the top object in the dependency tree and other classes should not use it, because it leads to circular dependencies problems, which is exactly what you're experiencing here. In other words a chicken and egg problem.
Design your app so that you have a one direction, upside down tree-like dependency structure. Don't access main window from lower level classes. Pass/retrieve data from them within main window instead of passing main window to them.
-
../JULY_30/30_work_1/CAT/mdi/form_setup.h:53:5: error: ‘MainWindow’ does not name a type;
If you want to use
MainWindow
inform_setup.h
you need to includemainwindow.h
there, but judging from the other error you seem to already have the reverse - you includeform_setup.h
inmainwindow.h
, so this can't work. Which leads me neatly to the other thing:I need to be able for other methods to access the "form".
That's usually a clear sign of badly designed app structure. The main window should usually be the top object in the dependency tree and other classes should not use it, because it leads to circular dependencies problems, which is exactly what you're experiencing here. In other words a chicken and egg problem.
Design your app so that you have a one direction, upside down tree-like dependency structure. Don't access main window from lower level classes. Pass/retrieve data from them within main window instead of passing main window to them.
@Chris-Kawa I am glad you replied.
I have been reading other posts and came to conclusion that I need to research my "application tree".I have
man
main window
MDI area
menu(s) (object )
and I desire communicate AKA "connect"
between menus / objects.All examples I have been studying have much simpler "tree"
main
mainwindow
objectand communicate AKA connect between main window and object .
I need to extend that to communicate BETWEEN objects.
As far as includes - my error pointed to such dependency. Unfortunately I forgot that I have added another "tree branch" and that made the includes even harder to manage
man
main window
MDI area
added here
common object
menu(s) (object )So my latest and still under development - temporary "attached " to lowest branch - the object itself - is global variable "MainWindow" .
Now before I get yelled for not doing object oriented stuff -
global access to "mainWindow" bypasses all the (unknown?) branches in-between , and will be used as "common / direct access to Main Window " from other menus / objects as necessary.
In other words - when communication between objects, physically displayed in MDI area, is desired it will be THRU / via "MainWindow" as used in many examples.In very real terms - when one menu / object scans for Bluetooth local adapters and one is selected to be actually used in Bluetooth communication - such selection needs to be passed to another menu / object where other parameters of Bluetooth , such as class of service , can be determined . ( Yes- it could be done in same menu / window using "tab" ) .
Sound complicated , but my objective is to separate "setup" from actual communication , hence selectively using "window menu " AKA MDI area for each task.
-
@Chris-Kawa I am glad you replied.
I have been reading other posts and came to conclusion that I need to research my "application tree".I have
man
main window
MDI area
menu(s) (object )
and I desire communicate AKA "connect"
between menus / objects.All examples I have been studying have much simpler "tree"
main
mainwindow
objectand communicate AKA connect between main window and object .
I need to extend that to communicate BETWEEN objects.
As far as includes - my error pointed to such dependency. Unfortunately I forgot that I have added another "tree branch" and that made the includes even harder to manage
man
main window
MDI area
added here
common object
menu(s) (object )So my latest and still under development - temporary "attached " to lowest branch - the object itself - is global variable "MainWindow" .
Now before I get yelled for not doing object oriented stuff -
global access to "mainWindow" bypasses all the (unknown?) branches in-between , and will be used as "common / direct access to Main Window " from other menus / objects as necessary.
In other words - when communication between objects, physically displayed in MDI area, is desired it will be THRU / via "MainWindow" as used in many examples.In very real terms - when one menu / object scans for Bluetooth local adapters and one is selected to be actually used in Bluetooth communication - such selection needs to be passed to another menu / object where other parameters of Bluetooth , such as class of service , can be determined . ( Yes- it could be done in same menu / window using "tab" ) .
Sound complicated , but my objective is to separate "setup" from actual communication , hence selectively using "window menu " AKA MDI area for each task.
global variable "MainWindow"
I'm far from being an object oriented devotee, but a global object like that is a bad idea for reasons unrelated to oop. The problem is this way you let go of any control over dependencies. Everything has access to everything from everywhere is a great way to make code that resembles a bowl of spaghetti.
Qt examples are meant to show usage of particular features and classes. They are not exactly focused on application architecture so don't draw too much inspiration from them in that sense.
Your hierarchy is not as complicated as you think. It's pretty standard actually. In terms of dependencies I'm proposing something like this. It doesn't have to be exactly a tree. The important part is that it flows in one direction, which makes managing includes and code in general far easier.
What you are describing on the other hand sounds something like this. I hope the picture shows how problematic in terms of dependency management this becomes and how it creates circular dependencies that are difficult and sometimes impossible to resolve.
-
global variable "MainWindow"
I'm far from being an object oriented devotee, but a global object like that is a bad idea for reasons unrelated to oop. The problem is this way you let go of any control over dependencies. Everything has access to everything from everywhere is a great way to make code that resembles a bowl of spaghetti.
Qt examples are meant to show usage of particular features and classes. They are not exactly focused on application architecture so don't draw too much inspiration from them in that sense.
Your hierarchy is not as complicated as you think. It's pretty standard actually. In terms of dependencies I'm proposing something like this. It doesn't have to be exactly a tree. The important part is that it flows in one direction, which makes managing includes and code in general far easier.
What you are describing on the other hand sounds something like this. I hope the picture shows how problematic in terms of dependency management this becomes and how it creates circular dependencies that are difficult and sometimes impossible to resolve.
@Chris-Kawa
Lovely! What tool do you use to generate these diagrams? -
@Chris-Kawa
Lovely! What tool do you use to generate these diagrams? -
@Chris-Kawa Blimey!!
-
@Chris-Kawa Blimey!!
@JonB Thanks for chiming in - I have been looking for "simple IBM flow charting software. I still own TWO of the original templates !
Chis , I really appreciate your time spending on this.
At this point I am heading in TWO directions - use global variable to build necessary " connect " in both object and mainwindow. I have that partially working "within" object.Secondly shuffle the "include" mess so it will work WITHOUT the use of global variable.
I am actually going to use your flow to find where to put the code to let one object reuse the menu and create instance of another object.
Actually I would prefer to add another menu instead - to have "top down " hierarchy
Sort of
user instruction object
object object object...I am not so sure how to implement that....
PS
I wonder if I can copy your flowchart and import them to www.draw.io -
I wonder if I can copy your flowchart and import them to www.draw.io
Sorry, normally you can share the graphs themselves in one of the graph formats supported, but I just exported them as images and didn't kept originals. Shouldn't be too hard to recreate them though if you want to. It took me like 5 minutes to make them.
Just a note so you don't get the wrong impressions. These charts are only meant to represent dependencies, not which code calls what and whether to use connections or something else. You can actually implement the bad and the good model using the same tools, it's just a matter of arranging them.
For example, this is a simple one way dependency:
struct Data { ... }; class Dialog { public slots: void doSomething(const Data& data) { emit somethingHappened(data); } signals: void somethingHappened(const Data& data); }; class MainWindow { MainWindow() { connect(&dialog, &Dialog::somethingHappened, this, &MainWindow::doSomething); Data data; dialog.doSomething(data); } void doSomething(const Data& data) {} Dialog dialog; };
If you delete Dialog then MainWindow won't compile, but you can delete MainWindow and Dialog works without any changes. This is a one way dependency that would be represented like this:
But you can achieve exactly the same functionality with bad dependency management like this:
struct Data { ... }; class MainWindow; MainWindow* global; class Dialog { Dialog() { connect(this, &Dialog::somethingHappened, global, &MainWindow::doSomething); } public slots: void doSomething() { emit somethingHappened(global->data); } signals: void somethingHappened(const Data& data); }; class MainWindow { MainWindow() { global = this; dialog.doSomething(); } void doSomething(const Data& data) {} Data data; Dialog dialog; };
It does exactly the same but creates circular dependency. You can't delete one class without at least modifying the other. You also have a class declaration chicken and egg problem so it's actually hard to make this code compile. This would be the two way, or, in case of more classes, a circular dependency:
But, as you can hopefully see, it doesn't have anything to do with oop or any other buzz word. Both use the same tools - classes, signals and connects. It's just a matter of code layout and sitting with a pencil and a piece of paper to draw up dependencies before starting to code.