Hello I keep getting this
error: expected class-name before '{' token
{
^ line 15
what does this error mean exactly? Im attempting to inherit the controller class that has a function that I need to call in form1's cpp.
#ifndef FORM1_H
#define FORM1_H
#include <QDialog>
#include "controller.h"
namespace Ui {
class form1 ;
}
class form1 : public QDialog, public controller
{
Q_OBJECT
public:
explicit form1(QWidget *parent = 0);
~form1();
private slots:
void on_pushButton_clicked();
private:
Ui::form1 *ui;
};
#endif // FORM1_H
the controller class
#include "controller.h"
#include "ui_controller.h"
controller::controller(QWidget *parent) :
QWidget(parent),
ui(new Ui::controller) {
ui->setupUi(this);
show(1); }
void controller::show(int x) {
if(x==1)
{
myform1 = new form1(this);
myform1->show();
}
if(x==2)
{
myform2 = new form2(this);
myform2->show();
}
if(x==3)
{
myform3 = new form3(this);
myform3->show();
} }
controller::~controller() {
delete ui; }
controller.h:
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QWidget>
#include <form1.h>
#include <form2.h>
#include <form3.h>
namespace Ui {
class controller;
}
class controller : public QWidget
{
Q_OBJECT
public:
form1 * myform1;
form2 * myform2;
form3 * myform3;
void show(int x);
explicit controller(QWidget *parent = 0);
~controller();
private:
Ui::controller *ui;
};
#endif // CONTROLLER_H
My guess is you have a circular include issue, meaning controller.h includes, either directly or indirectly, form1.h.
EDIT: Change the include I was talking about to a forward declaration - you don't need the full definition of form1:
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QWidget>
class form1;
class form2;
class form3;
namespace Ui {
class controller;
}
class controller : public QWidget
{
//.................
//.................
Related
I am new in C++ Qt and struggling with the correct use of forward declarations and #include.
What I want to do:
I have a Qt Gui (Class Ui::Gui) where we can set values.
I want to save these values in Gui Class variables.
As soon as a button (Generate Xml) is clicked, I want to pass the object
'ui' to the XmlGeneratorClass, So i can use the values to generate a Xml.
gui.h
#ifndef GUI_H
#define GUI_H
#include <QMainWindow>
#include <QDebug>
#include "xmlgeneratorqobject.h"
namespace Ui {
class Gui;
}
class Gui : public QMainWindow
{
Q_OBJECT
public:
explicit Gui(QWidget *parent = nullptr);
~Gui();
qint8 testvalue = 1;
signals:
void transmitToXmlGen(Ui::Gui*);
private slots:
void on_pushButtonGenerateXml_clicked();
private:
Ui::Gui *ui;
XmlGeneratorQObject *xmlgenerator = new XmlGeneratorQObject();
};
#endif // GUI_H
gui.cpp
#include "gui.h"
#include "ui_gui.h"
Gui::Gui(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Gui)
{
ui->setupUi(this);
connect(this,SIGNAL(transmitToXmlGen(Ui::Gui*)),xmlgenerator,SLOT(receiveFromGui(Ui::Gui*)));
}
Gui::~Gui()
{
delete ui;
}
void Gui::on_pushButtonGenerateXml_clicked()
{
emit transmitToXmlGen(ui);
}
xmlgeneratorqobject.h
#ifndef XMLGENERATORQOBJECT_H
#define XMLGENERATORQOBJECT_H
#include <QObject>
#include <QDebug>
namespace Ui {
class XmlGeneratorQObject;
class Gui;
}
class XmlGeneratorQObject : public QObject {
Q_OBJECT
public:
explicit XmlGeneratorQObject(QObject * parent = nullptr);
private slots:
void receiveFromGui(Ui::Gui*);
};
#endif // XMLGENERATORQOBJECT_H
xmlgeneratorqobject.cpp
#include "xmlgeneratorqobject.h"
XmlGeneratorQObject::XmlGeneratorQObject(QObject *parent){}
void XmlGeneratorQObject::receiveFromGui(Ui::Gui* objectFromGui)
{
qDebug() << objectFromGui->testvalue; // ERROR member access into incomplete type 'Ui::Gui'
}
Expected result:
Access to public variables from passed gui-object should be possible
Actual result:
member access into incomplete type 'Ui::Gui'
Can you please help me learn forward declaration / include?
Is my approach in general okay?
Your xmlgeneratorqobject.cpp needs the line
#include "ui_gui.h"
This gives it the details of the ui widgets. This file is generated by the Qt build system.
I have a QMainWindow Application which also includes an QStackedWidget.
The pages of the QstackedWidget are promoted to ui widgets for example heating_widget.ui
If I use a button slot on my QMainWindow I can use this to get my application to fullscreen:
void SmartHome::on_fullscreen_on_clicked()
{
SmartHome::setWindowState(Qt::WindowFullScreen);
}
But how can I do this from a button which is in the heating_widget.cpp file?
Using:
void heating_widget::on_fullscreen_on_clicked()
{
SmartHome::setWindowState(Qt::WindowFullScreen);
}
obviously doesn't work and throws this error at me:
cannot call member function 'void
QWidget::setWindowState(Qt::WindowStates)' without object
SmartHome::setWindowState(Qt::WindowFullScreen);
I know this has something to do with parent() but I can't get it to work.
Do you have any idea?
My smarthome.h file:
#ifndef SMARTHOME_H
#define SMARTHOME_H
#include <QTime>
#include <QMainWindow>
namespace Ui {
class SmartHome;
}
class SmartHome : public QMainWindow
{
Q_OBJECT
public:
explicit SmartHome(QWidget *parent = 0);
~SmartHome();
private slots:
void on_Info_Button_clicked();
void on_News_Button_clicked();
void on_Heating_clicked();
void timerslot();
void on_Config_clicked();
void on_About_clicked();
public slots:
void setFullscreen();
private:
Ui::SmartHome *ui;
QTimer* myTimer;
};
#endif // SMARTHOME_H
My heating_widget.h :
#ifndef HEATING_WIDGET_H
#define HEATING_WIDGET_H
#include "smarthome.h"
#include <QWidget>
namespace Ui {
class heating_widget;
class SmartHome;
}
class heating_widget : public QWidget
{
Q_OBJECT
public:
explicit heating_widget(QWidget *parent = 0);
~heating_widget();
private slots:
void on_fullscreen_on_clicked();
private:
Ui::heating_widget *ui;
};
#endif // HEATING_WIDGET_H
and my heating.widget.cpp:
#include "heating_widget.h"
#include "ui_heating_widget.h"
#include "smarthome.h"
#include "iostream"
heating_widget::heating_widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::heating_widget)
{
ui->setupUi(this);
QObject::connect(ui->fullscreen_on, SIGNAL(clicked()), this , SLOT(SmartHome::setFullscreen()));
}
heating_widget::~heating_widget()
{
delete ui;
}
void heating_widget::on_fullscreen_on_clicked()
{
parentWidget()->setWindowState(Qt::WindowFullScreen);
std::cout<<"clicked"<<std::endl;
}
I would do it in the following way:
void heating_widget::on_fullscreen_on_clicked()
{
foreach(QWidget *widget, QApplication::topLevelWidgets()) {
if (auto mainWindow = qobject_cast<SmartHome *>(widget)) {
mainWindow->setWindowState(Qt::WindowFullScreen);
}
}
}
The idea is finding your main window among application top level widgets and change its state. This code can be called from anywhere in your application regardless of the windows hierarchy.
In one of my project, I am trying to use the Qt signals and slots mechanism with a std::vector<bool> as parameter. My project is equivalent to the following minimal code :
class App
// app.h
#ifndef APP_H
#define APP_H
#include <QObject>
#include <QSharedPointer>
#include "emitter.h"
#include "receiver.h"
class App : public QObject
{
Q_OBJECT
public:
App(QObject *parent = 0);
};
#endif // APP_H
// app.cpp
#include "app.h"
App::App(QObject* parent): QObject(parent)
{
Emitter emitter;
Receiver receiver;
receiver.attachEmitter(emitter);
emitter.run();
}
class Emitter
//emitter.h
#ifndef EMITTER_H
#define EMITTER_H
#include <QObject>
#include <vector>
#include "helper.h"
class Helper;
class Emitter : public QObject
{
Q_OBJECT
public:
explicit Emitter(QObject *parent = 0);
void run();
signals:
void triggered(std::vector<bool> value);
};
#endif // EMITTER_H
// emitter.cpp
#include "emitter.h"
Emitter::Emitter(QObject *parent) : QObject(parent)
{
}
void Emitter::run()
{
emit triggered(Helper::value());
}
class Receiver
//receiver.h
#ifndef RECEIVER_H
#define RECEIVER_H
#include <QObject>
#include <QDebug>
#include <QSharedPointer>
#include "emitter.h"
class Emitter;
class Receiver : public QObject
{
Q_OBJECT
public:
explicit Receiver(QObject *parent = 0);
void attachEmitter(QSharedPointer<Emitter> emitter);
signals:
public slots:
};
//receiver.cpp
#include "receiver.h"
Receiver::Receiver(QObject *parent) : QObject(parent)
{
}
void Receiver::attachEmitter(QSharedPointer<Emitter> emitter)
{
connect(emitter.data(), &Emitter::triggered, [this](std::vector<bool> value) {
qDebug() << "Received value";
});
}
For some reason, the compiler doesn't like it at all and prints me this stack :
What do I have to do ? Thank you
Signal/slot values passend by value have to be registered with the Qt meta system and I don't think the std::vector is registered by default. Is there a reason you're not using QVectorinstead?
For futher information look at Q_DECLARE_METATYPE and qRegisterMetaType().
Getting error while declaring QVector of class type in Qt.
Error :"incomplete type is not allowed"
I didn't understand what causes this error.
if i #include "storage.h" in main.cpp and declare a Qvector of class storeage it works fine but when i do the same in waveform class it reports an error.
I've tried forward declaring storage class in waveform class but still getting the same error.
Any Help??
main.cpp
#include "test_subject_02.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TEST_SUBJECT_02 w;
w.show();
return a.exec();
}
test_subject_02.h
#ifndef TEST_SUBJECT_02_H
#define TEST_SUBJECT_02_H
#include <QtGui/QMainWindow>
#include "ui_test_subject_02.h"
#include"waveform.h"
#include "storage.h"
class TEST_SUBJECT_02 : public QMainWindow
{
Q_OBJECT
public:
TEST_SUBJECT_02(QWidget *parent = 0, Qt::WFlags flags = 0);
waveform *wv;
~TEST_SUBJECT_02();
private:
Ui::TEST_SUBJECT_02Class ui;
};
#endif // TEST_SUBJECT_02_H
test_subject_02.cpp
#include "test_subject_02.h"
TEST_SUBJECT_02::TEST_SUBJECT_02(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
QVector<storage> ser; //works fine here
wv->readfile("e:/testing2/result/3/abc.cur");
}
TEST_SUBJECT_02::~TEST_SUBJECT_02()
{
}
waveform.h
#ifndef WAVEFORM_H
#define WAVEFORM_H
#include "storage.h"
#include <QObject>
class waveform : public QObject
{
Q_OBJECT
public:
waveform(QObject *parent=0);
void readfile(QString);
QVector <storage> myvector ; // incomplete type is not allowed
~waveform();
private:
};
#endif // WAVEFORM_H
waveform.cpp
#include "waveform.h"
waveform::waveform(QObject *parent)
: QObject(parent)
{
}
void waveform::readfile(QString file)
{
QVector<storage> sw; //again error incomplete type is not allowed
}
waveform::~waveform()
{
}
storage.h
#ifndef STORAGE_H
#define STORAGE_H
#include <QObject>
class storage : public QObject
{
Q_OBJECT
public:
storage(QObject *parent);
storage();
storage(QString,QString);
~storage();
private:
QString x;
QString y;
};
#endif // STORAGE_H
storage.cpp
#include "storage.h"
storage::storage(QObject *parent)
: QObject(parent)
{
}
storage::storage(QString xcord,QString ycord)
{
x=xcord;
y=ycord;
}
storage::storage()
{
}
storage::~storage()
{
}
You need to explicitly include QVector in necessary file (waveform.h i believe), since QT uses a lot of forward declarations, while they appear as correct classes in IDE, but they won't compile, if proper definition is not included in file.
I cannot access staticmetaobject and I dont know why. I would need some help.
Here is the code
The two errors are:
staticMetaObject is not a member of MainWIndow*
I feel like it has something to do with the list, but I'm not sure.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "form.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Form<MainWindow*>* form;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*qDebug() << MainWindow::staticMetaObject.className();
if (QString(MainWindow::staticMetaObject.className()) == QString("MainWindow")) {
qDebug() << "test";
}*/
form = new Form<MainWindow*>(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
form->myFunc();
}
form.h
#ifndef FORM_H
#define FORM_H
#include <QObject>
#include <QDebug>
class FormBase : public QObject
{
Q_OBJECT
public:
FormBase() {}
};
template <typename T>
class Form : public FormBase, public QList<T>
{
public:
Form(T a)
{
QList<T>::append(a);
}
void myFunc()
{
qDebug() << T::staticMetaObject.className();
}
};
#endif // FORM_H
You are getting you types confused.
You want T to be MainWindow so that you can do
T::staticMetaObject.className()
That means you want a QList<T*>. You derive from that so you can just call
append(a);
The following code compiles fine:
class FormBase : public QObject
{
Q_OBJECT
public:
FormBase() {}
};
template <typename T>
class Form : public FormBase, public QList<T*>
{
public:
Form( T* a )
{
append( a );
}
void myFunc()
{
qDebug() << T::staticMetaObject.className();
}
};
class MainWindow:
public QMainWindow
{
MainWindow()
{
form = new Form<MainWindow>( this );
}
FormBase* form;
};