In my application I'm having 2 widgets named as widget and form. But if i try to create a pointer object of widget widget in widget form header file , it is giving the error like "Form does not name a type". Refer my used code below:
main.cpp
#include <QtGui/QApplication>
#include "widget.h"
#include "form.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget *w = new Widget();
w->show();
return a.exec();
}
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent) :QWidget(parent)
{
setupUi(this);
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include "ui_widget.h"
#include "form.h"
class Widget : public QWidget, private Ui::Widget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
Form *f ;//i try to create pointer object for Form
};
#endif // WIDGET_H
form.cpp
#include "form.h"
#include "widget.h"
Form::Form(QWidget *parent) :QWidget(parent)
{
setupUi(this);
}
form.h
#ifndef FORM_H
#define FORM_H
#include "ui_form.h"
#include "widget.h"
class Form : public QWidget, private Ui::Form
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
};
What I'm doing wrong?
The problem is that widget.h includes form.h, which includes widget.h. The header guards (#ifndef) cause the second include to be skipped.
For declaring a pointer variable in a header a forward declaration will suffice:
SomeClass.h
class Form; // forward declaration
class SomeClass {
public:
SomeClass();
// ...
private:
Form* form; // pointer to Form
};
SomeClass.cpp
SomeClass::SomeClass()
{
form = new Form();
}
You should put a forward declaration of class Form in widget.h instead of #includeing form.h. The problem is that you include form.h, which includes widget.h, which tries to include form.h, but can't because of the include guard. Therefore, in widget.h, class Form is undefined, although it looks to the user to be defined.
Related
I'm trying to understand the automatically code generated why QT when creating a QWidget with a Form.
This is the code generated by QT:
**********************************************************************
* widget.h
**********************************************************************
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#endif // WIDGET_H
**********************************************************************
* widget.cpp
**********************************************************************
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
**********************************************************************
* main.cpp
**********************************************************************
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
My question is with this statement in the constructor:
ui(new Ui::Widget)
This is creating a new Widget when the constructor of class Widget is called.
It's like recurssion isn't it? Why doesn`t it break?
It is not recursive it s the instance of your ui_Widget.h Class since you need only one instance of your GUI at a time
The advantage of this approach is that the user interface object can be forward-declared, which means that we do not have to include the generated ui_Widget.h file in the header. The form can then be changed without recompiling the dependent source files. This is particularly important if the class is subject to binary compatibility restrictions.because as you can see the " #include "ui_widget.h"
is inside the cpp a not in the headers file
NO. Because of namespaces there are two different classes with the same name:
Ui::Widget
and
Widget
Ui::Widget is the class for the form object.
I make a project of music player in Qt based on QWidget class
and using widget.ui form.
I want to check that user will not add two labels with the same text, so I'm trying to add field: QList labelsList;
in my widget.h file.
(every time user add label, than: labelsList.append(label), and before he can add this label program would iterate through labelsList and check if in list exists label with patricular text).
Although "myqlabel.h" is included, compiler says that 'myQLabel' was not declared in this scope... I don't know why. Kind of weird for me, but maybe I lack/forget some basic knowledge... ;/
Thanks for help!
Code (just needed fragments) below:
widget.h file:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "myqlabel.h"
#include <QList>
#include <QFormLayout>
#include <QSqlDatabase>
#include <QtSql>
#include <QMediaPlayer>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
// to check if label with input text already exists:
// HERE OUR BAD FIELD:
QList<myQLabel*> labelsList;
private:
Ui::Widget *ui;
QMediaPlayer player;
qint64 duration;
};
#endif // WIDGET_H
myqlabel.h file:
#ifndef MYQLABEL_H
#define MYQLABEL_H
#include <QLabel>
#include "widget.h"
#include "ui_widget.h"
#include <QFormLayout>
#include <QMouseEvent>
class myQLabel : public QLabel {
Q_OBJECT
public:
myQLabel(QString& text, QFormLayout* parent = 0) : QLabel(text){
setAcceptDrops(true);
position = amount;
this->parent = parent;
labelsList.append(this);
}
};
#endif // MYQLABEL_H
You have a circular dependency in your includes. This means that one of the headers is not seen depending on the order in which they are first included (due to the include guards).
Remove #include "myqlabel.h" from widget.h and add it to widget.cpp. Then forward declare myQLabel by adding
class myQLabel;
to widget.h.
In my application im having three widgets named as "Widget" , "one" and "two" . i tried to create the objects of the widget in main function as pass it as an argument to another widgets . it compiles successfully but application crashed before running , refer my code below and guide me,
//main.cpp
#include <QtGui/QApplication>
#include "widget.h"
#include "one.h"
#include "two.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget *w;
One *one;
Two *two;
w->GetObject(one,two);
one->GetObject(w,two);
two->GetObject(one,w);
w->show();
return a.exec();
}
//widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent) :QWidget(parent)
{
setupUi(this);
}
void Widget::GetObject(One *onee, Two *twoo)
{
one=onee;
two=twoo;
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include "ui_widget.h"
class One;
class Two;
class Widget : public QWidget, private Ui::Widget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
One *one;
Two *two;
void GetObject(One *onee, Two *twoo);
};
#endif // WIDGET_H
//one.cpp
#include "one.h"
One::One(QWidget *parent) :QWidget(parent)
{
setupUi(this);
}
void One::GetObject(Widget *widgett, Two *twoo)
{
widget = widgett;
two = twoo;
}
void One::on_pushButton_clicked()
{
widget->show();
}
//one.h
#ifndef ONE_H
#define ONE_H
#include "ui_one.h"
class Widget;
class Two;
class One : public QWidget, private Ui::One
{
Q_OBJECT
public:
explicit One(QWidget *parent = 0);
Widget *widget;
Two *two;
void GetObject(Widget *widgett, Two *twoo);
private slots:
void on_pushButton_clicked();
};
#endif // ONE_H
When I add slots to my script it will no longer build.
inkpuppet.obj:-1: error: LNK2005: "private: void __cdecl InkPuppet::on_aboutButton_clicked(void)" (?on_aboutButton_clicked#InkPuppet##AEAAXXZ) already defined in main.obj
and
debug\InkPuppet.exe:-1: error: LNK1169: one or more multiply defined symbols found
Here is the code:
inkpuppet.h - commenting out void on_aboutButton_clicked(); and the function at the end will make it run.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtCore>
namespace Ui {
class InkPuppet;
}
class InkPuppet : public QWidget
{
Q_OBJECT
public:
explicit InkPuppet(QWidget *parent = 0);
~InkPuppet();
private:
Ui::InkPuppet *ui;
private slots:
void on_aboutButton_clicked();
};
#endif // WIDGET_H
void InkPuppet::on_aboutButton_clicked()
{
}
inkpuppet.cpp
#include "inkpuppet.h"
#include "ui_inkpuppet.h"
InkPuppet::InkPuppet(QWidget *parent) :
QWidget(parent),
ui(new Ui::InkPuppet)
{
ui->setupUi(this);
//connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)), ui->timeSlider, SLOT(setRange(int,int)));
}
InkPuppet::~InkPuppet()
{
delete ui;
}
main.cpp
#include "inkpuppet.h"
#include "aboutdialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
InkPuppet w;
w.show();
return a.exec();
}
aboutdialog.h
#ifndef ABOUTDIALOG_H
#define ABOUTDIALOG_H
#include <QDialog>
namespace Ui {
class AboutDialog;
}
class AboutDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutDialog(QWidget *parent = 0);
~AboutDialog();
private:
Ui::AboutDialog *ui;
};
#endif // ABOUTDIALOG_H
aboutdialog.cpp
#include "aboutdialog.h"
#include "ui_aboutdialog.h"
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutDialog)
{
ui->setupUi(this);
}
AboutDialog::~AboutDialog()
{
delete ui;
}
You define your void InkPuppet::on_aboutButton_clicked() in your inkpuppet.h. And then you include it in inkpuppet.cpp AND in main.cpp -> one or more multiply defined symbols found.
Put
void InkPuppet::on_aboutButton_clicked()
{
}
in your inkpuppet.cpp file.
If the first file you pasted is a whole, there's a problem with the include guards. The definition is after the guard's end.
#endif // WIDGET_H
void InkPuppet::on_aboutButton_clicked()
{
}
Your definition is right after the #endif which means as soon as in the same translation unit, the header is included twice, you'll get this error. And this happens in your code because inkpuppet.h is included in both main.cpp and in inkpuppet.cpp You should put the implementation code for on_aboutButton_clicked() in your inkpuppet.cpp file.
Not sure this issue about Qt or C++ in general, I'm just a newbie for both of these!
I got a simple Qt app, with a MainWindow and Hello class like below:
hello.h
#ifndef HELLO_H
#define HELLO_H
#include <QWidget>
#include "mainwindow.h"
class Hello : public QWidget
{
Q_OBJECT
public:
explicit Hello(MainWindow *parent = 0);
signals:
public slots:
};
#endif // HELLO_H
heloo.cpp
#include "hello.h"
Hello::Hello(MainWindow *parent) :
QWidget(parent)
{
//nothing here yet
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
#include "hello.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Hello* hi;
};
#endif // MAINWINDOW_H
mainwindows.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
hi = new Hello(this);
}
MainWindow::~MainWindow()
{
}
main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
and here is the error when I build my project:
from ../untitled1/main.cpp:2: ../untitled1/hello.h:11: error: expected
‘)’ before ‘*’ token
and the line cause the error is:
explicit Hello(MainWindow *parent = 0);
Can you help me to resolve the issue!
Thanks you!
You have circular inclusion of header files in "hello.h" and "maindwindow.h". There is no need to include these files in the header file as you are just using a pointer. A simple forward declaration such as class MainWindow; in "hello.h" is sufficient.