Circular dependencies with headers. Using #ifndef and #define - c++

I have the very simple following code:
main.cpp
#include "ui_library_browser.h"
#include <QtGui/QApplication>
#include "StartWindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
StartWindow w;
w.show();
return a.exec();
}
StartWindow.h
#ifndef STARTWINDOW_H_
#define STARTWINDOW_H_
#include <qwidget>
#include "MainWindow.h"
class StartWindow : public QWidget
{
Q_OBJECT
public:
StartWindow();
~StartWindow();
MainWindow main_window; //<-- Problem
};
#endif
MainWindow.h
#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include <qdialog.h>
#include "StartWindow.h"
class MainWindow : public QDialog
{
Q_OBJECT
public:
MainWindow();
~MainWindow();
};
#endif
This produces errors because of the inclusion of #include "StartWindow.h" in the MainWindow.h header. However, I thought the use of #ifndef and #define are to stop problems like this? Can someone clear this up for me?

So called "header guards" are used to prevent a bit different kind of error: including same header multiple time through different indirect inclusions in one compile unit. For example,
you include "a.h" from main.cpp and then include "b.h" from main.cpp, that includes "a.h" itself somewhere inside.
In your case two headers try to include each other circurally, that is not possible - C/C++ preprocessor works as simple text "copy-paste" and this case would invent infinite recursion of text insertion.
And I really don't see why would you need "StartWindow.h" inclusion in "MainWindow.h" header.

Do you use StartWindow in MainWindow? If not, simply remove the StartWindow.h include. Otherwise make the main_window a pointer instead of a variable.

In the file StartWindow.h remove #include "MainWindow.h" and add the forward declaration (before class StartWindow ...):
class MainWindow;
In the same file change the member MainWindow main_window to
const MainWindow* main_window;
or
const MainWindow& main_window;
In the latter case you would need to pass const MainWindow& in the constructor of StartWindow.

Related

How do I use Objective-C variables and methods for a Qt window on macOS?

I have the following code in a Qt project, and I want to set the titlebarAppearsTransparent variable for a window to true in Objective-C. The program compiles correctly, but it crashes when it reaches [&w titlebarAppearsTransparent:YES]; Is what I'm trying to do even possible, and if so how do I fix it?
#include "mainwindow.h"
#include <QApplication>
#include <QFile>
#include <QDebug>
#include <QDir>
#include "globals.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <AppKit/NSWindow.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QApplication::setOrganizationName("Siddha Tiwari");
QApplication::setApplicationName("NarwhalEdit");
MainWindow *w = new MainWindow();
[&w titlebarAppearsTransparent:YES];
setTheme(true);
w->show();
return a.exec();
}
It is possible to accomplish this using the native API, as reported here, obtaining the NSWindow pointer from QWidget::window()::winId().
I would also suggest to wrap the code with conditional compiling directives, so it is ignored when compiling for other platforms.
Here is a snippet (assuming w is the pointer to your QMainWindow):
#ifdef Q_OS_MAC
QCoreApplication::setAttribute( Qt::AA_DontCreateNativeWidgetSiblings );
NSView *nsview = ( __bridge NSView * )reinterpret_cast<void *>( w->window()->winId() );
NSWindow *nswindow = [nsview window];
nswindow.titlebarAppearsTransparent = YES;
#endif

Qt: "Expected type-specifier" appearing on one device and not another with same code

A friend and I are beginners with C++ and Qt. We are working on a Qt project together (the helicopter game) and when she sent me the code she had on her computer, which ran without errors, it gave the "expected type-specifier" error on a line that set a pointer equal to a new instance our "game" constructor. Is there something wrong with the code or does it have something to do with my computer?
This is where our error appears in the main function:
#include <QApplication>
#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include <QGraphicsView>
#include <QGraphicsScene>
//including for splash screen
#include <QSplashScreen>
#include <QTimer>
//our header files
#include "player.h"
#include "game.h"
game * heli_game;
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QSplashScreen * splash = new QSplashScreen;
splash->setPixmap(QPixmap(":/images/splash.png"));
splash->show();
game * heli_game;
heli_game = new game::game(); //ERROR HERE: "expected type-specifier"
QTimer::singleShot(2500, splash, SLOT(close()));
return a.exec();
}
And here's our game header file where the constructor is defined:
#ifndef GAME
#define GAME
#include <QGraphicsView>
#include <QWidget>
#include <QGraphicsScene>
#include "player.h"
#include "score.h"
//#include "game_over.h"
class game: public QGraphicsView{
Q_OBJECT
public:
//constructors
game(QWidget* parent=NULL);
//public attributes
QGraphicsScene * scene;
player * copter;
score * Score;
// game_over * game_over;
};
#endif // GAME
new game::game();
^ This would only make sense if the game class is in a namespace called game. Since it isn't, the compiler has no way of knowing what type you're referring to.
What you probably meant to do was this:
new game();
I should also point out that heli_game is declared twice in your main file.
heli_game = new game::game();
is incorrect, it should be
heli_game = new game();
only. Your code shouldn't have compiled with any compiler.
By the way you have a "heli_game *game" global variable and another inside main().

Qt Error: Can't declared multiple mainwindows in main.cpp

In "main.cpp":
#include "mainwindow.h"
#include "mainwindow_1.h"
And I code in main.cpp:
MainWindow *mainWin_1 = new MainWindow;
MainWindow_1 *mainWin_2 = new MainWindow_1;
I'm already declared MainWindow and MainWindow_1 in "mainwindow.h" and "mainwindow_1.h". They are both QMainWindow. But when I debug, I got an error that said "MainWindow_1 was not declared in this scope".
When I changed:
#include "mainwindow.h"
#include "mainwindow_1.h"
into
#include "mainwindow_1.h"
#include "mainwindow.h"
I got the error "MainWindow was not declared in this scope".
Can I only include one mainwindow? How can I get two QMainwindow in main.cpp without error?
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDateTime>
#include <ctime>
class MainWindow : public QMainWindow {
Q_OBJECT;
public:
MainWindow();
~MainWindow();
};
#endif
mainwindow_1.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDateTime>
#include <ctime>
class MainWindow_1 : public QMainWindow {
Q_OBJECT;
public:
MainWindow_1();
~MainWindow_1();
};
#endif
Sounds like you have same include guard macro in both .h files.
So, change both the #ifndef and #define near beginning of one of the .h files to be different from the include guards of the other .h file.
For example change mainwindow_1.h to have this:
#ifndef MAINWINDOW_1_H
#define MAINWINDOW_1_H
When you have same include guard macro, then the contents of the file included later will be skipped, and the class in it will be left undefined in that .cpp file.
One thing to keep in mind is, C++ include files are not like "import" or such of many other languages. #include just inserts contents of the other file into the compilation, same as if you copy-pasted it. Among other things, this means that later include file "sees" all macros defined in earlier include files, so include guards must have unique names.

Can't register C++ type to QML system

I'm trying to add C++ type to QML system.
#include <QtGui/QGuiApplication>
#include <QDeclarativeEngine>
#include <QDeclarativeComponent>
#include "qtquick2applicationviewer.h"
#include <QQmlApplicationEngine>
class FooBar: public QObject {
Q_OBJECT
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine("qml/RBot/main.qml");
qmlRegisterType<FooBar>("io.secorp", 1, 0, "FooBar");
return app.exec();
}
But when I'm trying compile this(i don't import this in .qml file, only testing) I'm geting errors about debugging.
What's wrong?
Thanks.
You're mixing Qt Quick 1 and 2, which is unsupported. The QDeclarative headers are for Quick 1 and the QQml headers are for Quick 2.
Your includes should be:
#include <QtGui/QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include "qtquick2applicationviewer.h"
#include "foobar.h"
The definition of FooBar should be in its own header, and QObject should be included there for moc to work its magic.
For more details, see this already reported bug in Qt:
QTBUG-32138 - Hello World for QtQuick2 does not compile with #include when QML debugging is on

Qt 5.0 including personal header issues

look i'm kind of new to programming in c++ with Qt so i've downloaded the 5.0 version on my win 7 64 bit. i have made a class named Mafenetre and i implemented its code and it seems perfect but when i i try to run the main program it says
C:\Users\Zbart3i\Downloads\Programs\test\main.cpp:3: error: C1083: Cannot open include file: 'Mafenetre.h': No such file or directory
this is my pro code:
SOURCES += \
main.cpp \
mafenetre.cpp
QT+=widgets
HEADERS += \
mafenetre.h
this is code of Mafenetre.h:
#ifndef MAFENETRE_H
#define MAFENETRE_H
include < QtWidgets>
class Mafenetre:public QWidget
{
public:
Mafenetre();
private:
QPushButton *m_bouton;
};
#endif // MAFENETRE_H
this is Mafenetre's.cpp:
#include "mafenetre.h"
Mafenetre::Mafenetre():QWidget()
{
setFixedSize(300,150);
m_bouton=new QPushButton("pimp mon bouton",this);
m_bouton->setFont(QFont("monotype corsiva",15));
m_bouton->setCursor(Qt::PointingHandCursor);
}
and the main.cpp
#include< QtWidgets/QApplication>
#include< QtWidgets>
#include< Mafenetre.h>
void main(int argc, char *argv[])
{
QApplication app(argc, argv);
Mafenetre fenetre;
fenetre.show();
app.exec();
}
In C++, you should use the #include "name", not #include (Quote marks instead of triangle brackets), as they have different meanings.
#include looks in certain directories where libraries (including the standard library) is installed.
#include "name" looks first in your project's folders, and then checks the other directories.
Well, to be technically accurate, what folders they look in, and in one order, is compiler-specific.
This:
#include <Mafenetre.h>
Should be this:
#include "Mafenetre.h"
Read this:
MinGW #include search directories
Other Directories Searched by Default
The minimal list of directories, identified as described
above, specifies the only locations which will be searched by default,
for system header files or for headers associated with user installed
libraries; however, there is one exception. Astute readers may have
noticed that the include file search path is itemised in a pair of
sequential lists, with the second being concatenated to the first;
however, the first, identified as the #include "..." search list
appears to be empty. In reality, this apparent emptiness is possibly
misleading; unless the user specifies the "-I-" option when invoking
GCC, this list contains exactly one directory: the directory in which
the source file containing the #include "file" directive resides.
Notice that this one additional directory is not searched for headers specified with the #include <file> form of the #include directive; it applies only for those headers specified using the #include "file" form of the directive.
And make sure your "Mafenetre.h" file is in the same folder as your main.cpp file. Otherwise you need to do #include "folderPath/fileName.h", and also add the path to the SOURCES or HEADERS variables in the .pro file.
Also make sure the spelling is identical, and that the proper case is used - sometimes it matters, sometimes it doesn't.
If you are still having trouble, try to compile a simple project consisting of just a single main.cpp, to make sure everything is installed correctly.
Are you sure you have included the right header. Also i don't see you using the QObject macro in your header file. It should be something like this:
Mafenetre.h:
#ifndef MAFENETRE_H
#define MAFENETRE_H
#include <QWidget>
class Mafenetre : public QWidget
{
Q_OBJECT
public:
explicit Mafenetre(QWidget *parent = 0);
signals:
public slots:
};
#endif // MAFENETRE_H
Mafenetre.cpp:
#include "mafenetre.h"
Mafenetre::Mafenetre(QWidget *parent) :
QWidget(parent)
{
}
Finally you main.cpp should be like this, check the headers:
......
#include "mafenetre.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Mafenetre m;
m.show();
return a.exec();
}