Switch windows in QT GUI app - c++

I am trying to make a link between my 3 windows , so I put this in my mainwindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "video.h"
#include "flightdata.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void openNewWindowVideo();
void openNewWindowData();
private:
Ui::MainWindow *ui;
video *myVideoWindow;
flightdata *myDataWindow;
};
#endif // MAINWINDOW_H
And this in my implementation:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionVideo,SIGNAL(triggered()),this,SLOT(openNewWindowVideo()));
connect(ui->actionFlight_data,SIGNAL(triggered()),this,SLOT(openNewWindowData()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::openNewWindowVideo()
{
myVideoWindow = new video();
myVideoWindow->show();
this->close();
}
void MainWindow::openNewWindowData()
{
myDataWindow = new flightdata();
myDataWindow->show();
this->close();
}
This works.
But when O follow the same steps for the 2 other windows ( file.h + file.cpp ),
iI get the error :
qt error: 'flightdata' does not name a type
qt error: 'video' does not name a type
But when I include just first window and not the 2 others , I don't get this problem.
Maybe it is being caused by recursion.

Don't include your other classes in header files. Include them in source files only.
If you for some reason need to use another class in a header of other class, use forward declaration instead of include.
Header:
// no include for 'video.h'
class video;
class MainWindow : public QMainWindow {
//...
video *myVideoWindow;
};
Source:
#include "video.h"
//...

As far as I can tell, there are potentially two things that may be wrong:
Pre-processor/MACRO
If you created the other windows with QtCreator/Designer, the #ifndef macros should be unique. Meaning, video.h should have something like:
#ifndef VIDEOWINDOW_H
#define VIDEOWINDOW_H
instead of the default
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
These #ifndef MACROS are intended to help include the contents of the header file once and only once.
Missing include paths
Also, if you're using QtCreator, the editor should display #include "video.h" and #include "flightdata.h" as a link (control + left click). If the syntax is underlined red, it means that the project can't find those files.
Then you'll need to check to make sure that the files are either in your project folder or add have the path to those files added in the qmake variable INCLUDEPATH of your pro file.
# e.g.
INCLUDEPATH += ../myflightdata ../myvideofiles

Related

Can we define static class member inside constructor? [duplicate]

This question already has answers here:
Why can't I initialize my static data member in my constructor
(5 answers)
Closed 6 years ago.
Say I have a static member defined in header file like:
static QHash<QString,int> flagColorsMap;
How can I define the hashmap inside the constructor that is in the cpp file. If I do the following:
Classname::flagColorsMap.insert("xyz",22);
it gives compile error :: undefined reference to Classname::flagColorMap.
In .cpp file put this line:
QHash<QString,int> Classname::flagColorsMap;
Edited:
Please check this really simple example of static QHash member initialization: create new Qt Quick project and edit MainWindow class:
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
static QHash<QString,int> flagColorsMap;
};
#endif // MAINWINDOW_H
And source file:
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
QHash<QString,int> MainWindow::flagColorsMap;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
MainWindow::flagColorsMap.insert("xyz",22);
}
MainWindow::~MainWindow()
{
qDebug() << "Value=" << flagColorsMap.value("xyz");
delete ui;
}
Is it still does not work?
I think you got this compile error because you are just "delcare" flagColorsMap but not "define" it.
So define flagColorsMap in the .cpp file maybe this error will disappeared.

QT Slots and signals, showing 2nd form/window

I have a QT application and I'm trying to have a button in one of my windows open another window.
The way I have done my window objects so far in the main is like this:
Website control;
control.show();
This displays my first window fine and if I declare my other window in a similar way that also displays at runtime, although this is not what I want
Then in a separate header file:
class Website: public QWidget, public Ui::Website
{
public:
Website();
}
Then in the corresponding Cpp file I have:
Website::Website()
{
setupUi(this);
}
Now all this works and have added a custom slot so that when I click a button it triggers a slot in my other cpp file. The issue is I'm not sure how to show my other window as I declare them in my main so can't access them to do .show()?
Any help would be appreciated, I'm fairly new to C++ and QT
It's not clear to me what you want to do. But i might understand your struggle as I had one myself the first time approaching this framework.
So let's say you have a MainWindow class that controls the main Window view. Than you want to create a second window controlled by Website class.
You then want to connect the two classes so that when you click a button on the Website window something happens in the MainWindow.
I made a simple example for you that is also on GitHub:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "website.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void changeText();
private slots:
void on_openButton_clicked();
private:
Ui::MainWindow *ui;
//You want to keep a pointer to a new Website window
Website* webWindow;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::changeText()
{
ui->text->setText("New Text");
delete webWindow;
}
void MainWindow::on_openButton_clicked()
{
webWindow = new Website();
QObject::connect(webWindow, SIGNAL(buttonPressed()), this, SLOT(changeText()));
webWindow->show();
}
website.h
#ifndef WEBSITE_H
#define WEBSITE_H
#include <QDialog>
namespace Ui {
class Website;
}
class Website : public QDialog
{
Q_OBJECT
public:
explicit Website(QWidget *parent = 0);
~Website();
signals:
void buttonPressed();
private slots:
void on_changeButton_clicked();
private:
Ui::Website *ui;
};
#endif // WEBSITE_H
website.cpp
#include "website.h"
#include "ui_website.h"
Website::Website(QWidget *parent) :
QDialog(parent),
ui(new Ui::Website)
{
ui->setupUi(this);
}
Website::~Website()
{
delete ui;
}
void Website::on_changeButton_clicked()
{
emit buttonPressed();
}
Project composed:
SOURCES += main.cpp\
mainwindow.cpp \
website.cpp
HEADERS += mainwindow.h \
website.h
FORMS += mainwindow.ui \
website.ui
Consider the Uis to be composed:
Main Window: a label called "text" and a button called "openButton"
Website Window: a button called "changeButton"
So the keypoints are the connections between signals and slots and the management of windows pointers or references.

qt c++ mysterious incomplete class type error on ui

I set up the skeleton for a multi-window qt project. It compiled ans was looking good, so I started adding all my gui elements and such. Now, all of a sudden, one of my windows is broken. Particularly, I'm having some trouble with this part in the header
namespace Ui {
class VideoPanel;
} ...
private:
Ui::VideoPanel *ui;
and the corresponding part in the cpp file:
VideoPanel::VideoPanel(QWidget *parent) :
QWidget(parent),
ui(new Ui::VideoPanel)
{
ui->setupUi(this); //
}
The error I get is
Error 1 error C2512: 'Ui::VideoPanel' : no appropriate default constructor available
on the line ui(new Ui::VideoPanel).
I have seen that if you don't include all the correct Qt gui headers, this can happen, so I've stripped everything out of my code except for the constructor and the destructor.
full h:
#ifndef VIDEOPANEL_H
#define VIDEOPANEL_H
#include <QtWidgets>
#include <QWidget>
namespace Ui {
class VideoPanel;
}
class VideoPanel : public QWidget
{
Q_OBJECT
public:
VideoPanel(QWidget *parent = 0);
~VideoPanel();
private slots:
private:
Ui::VideoPanel *ui;
};
#endif // VIDEOPANEL_H
full cpp:
#include "videopanel.h"
#include "ui_videopanel.h"
VideoPanel::VideoPanel(QWidget *parent) :
QWidget(parent),
ui(new Ui::VideoPanel)
{
ui->setupUi(this); //
}
VideoPanel::~VideoPanel()
{
}
you changed the name of your class, but the .ui file seems to have the old name in its <class> tag. you have to change the name there in order to have UIC generate a header file that is compatible with your new name.
To do so if you are using Qt Creator, you can open your ui file in the designer, and change the objectName property to your new class name, you may have to do a clean build after that.

Invalid use of incomplete type 'class Ui::dialog (QT error )

I would like to make a simple QT mainwindow with the button to open a second window or dialog. I followed literally the step from the QT link "Using a Designer UI File in Your Application" and following the single inheritance example.
But QT gives 4 errors , which you will see a snapshot of below.
Now, what I did is I created a mainwindow in Qt designer, then I added a second form to the project , which will be the second dialog window when a button clicked. Because I created the form manually "mydialog.ui", I added class "mydialog.h and mydialog.cpp" and put the header of "ui-mydialog" in the source file "mydialog.cpp".
I' not sure what am I missing ?
Below is the code :
- mydialog.h
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include<QWidget>
class mydialog ;
namespace Ui {
class mydialog;
}
class mydialog : public QWidget
{
Q_OBJECT
public:
explicit mydialog(QWidget *parent = 0);
virtual ~mydialog();
private :
Ui::mydialog *ui;
};
#endif // MYDIALOG_H
- mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtCore/QtGlobal>
#include <QMainWindow>
QT_USE_NAMESPACE
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class mydialog;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_Start_clicked();
private:
Ui::MainWindow *ui;
mydialog *dialog1;
};
#endif // MAINWINDOW_H
- mydialog.cpp
#include"mydialog.h"
#include "ui_mydialog.h"
mydialog::mydialog(QWidget *parent) : QWidget(parent), ui(new Ui::mydialog)
{
ui->setupUi(this);
}
mydialog::~mydialog()
{
delete ui;
}
- mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"mydialog.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
dialog1 = new mydialog ;
}
MainWindow::~MainWindow()
{
delete ui;
delete dialog1;
}
void MainWindow::on_Start_clicked()
{
}
- main.cpp
#include"mainwindow.h"
#include<QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
- The .pro file
#-------------------------------------------------
#
# Project created by QtCreator 2015-12-17T00:10:58
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = TestTool
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
mydialog.cpp
HEADERS += mainwindow.h \
mydialog.h
FORMS += mainwindow.ui \
mydialog.ui
RESOURCES += \
misc.qrc
- Qt compilation output error
Compilation error
The generated file Ui_mydialog.h is :
#ifndef UI_MYDIALOG_H
#define UI_MYDIALOG_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QDialog>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QHeaderView>
QT_BEGIN_NAMESPACE
class Ui_Dialog
{
public:
QDialogButtonBox *buttonBox;
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
Dialog->setObjectName(QStringLiteral("Dialog"));
Dialog->resize(400, 300);
buttonBox = new QDialogButtonBox(Dialog);
buttonBox->setObjectName(QStringLiteral("buttonBox"));
buttonBox->setGeometry(QRect(30, 240, 341, 32));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
retranslateUi(Dialog);
QObject::connect(buttonBox, SIGNAL(accepted()), Dialog, SLOT(accept()));
QObject::connect(buttonBox, SIGNAL(rejected()), Dialog, SLOT(reject()));
QMetaObject::connectSlotsByName(Dialog);
} // setupUi
void retranslateUi(QDialog *Dialog)
{
Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", 0));
} // retranslateUi
};
namespace Ui {
class Dialog: public Ui_Dialog {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MYDIALOG_H
This is because of the diferences between the names in your UI- und C++sourcecode files.
For example if in your UI-sourcecode file you have a name like "StatusBarPart"
but the name of your class in the C++ file is "StatusBar"
<class>StatusBarPart</class>
<widget class="QWidget" name="StatusBarPart">
StatusBar::StatusBar(QWidget *parent)
: PartBase(parent),
ui(new Ui::StatusBar)
then you you get these error message you see.
Solution:
You can edit the UI file in some external editor and make the names equal. Save changes. Compile your app. Be happy ;-)
You are mixing the name of the ui file with the name of the Ui class (objectName of the top level widget in QtDesigner).
For example, if QtDesigner looks like that:
You'll get a class names Ui::CalculatorForm, whatever the .ui file name is.
Replace Ui::mydialog by Ui::Dialog (or whatever the class name is in your generated ui_mydialog.h file)

How do I declare objects from my main window in Qt Creator?

This question should hopefully be easy to answer. I created a few buttons in my MainWindow using Qt Creator, and when I go to write the functions for the buttons, the compiler says they were not declared in this scope. What do I need to #include for these objects to be declared? The compiler error for the following would be 'baseDir' was not declared in this scope. baseDir is the objectName for a lineEdit in my window.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "ui_mainwindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void getDir();
void createProj();
private slots:
void on_findDir_clicked();
void on_create_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "functions.h"
#include <QtGui/QApplication>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_findDir_clicked()
{
QString path;
path = QFileDialog::getOpenFileName(
this,
"Choose a file to open",
QString::null,
QString::null );
baseDir->setText( path );
}
The items you define in your .ui file are not added directly to your main window class, they are added to its ui membre.
Try with:
ui->baseDir->setText( path );
Look at the ui_mainwindow.h file that is generated during the build if you're curious.