I am trying to create an object called x from a class "Fan" inside the QT GUI mainwindow file, where I want it to be global. I want QT's button slot functions to be able to perform operations on the object. However, a compiler error "error: C4430: missing type specifier - int assumed" always occurs. Here is the header file:
#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 slots:
void on_btOn_clicked();
void on_btOff_clicked();
private:
Ui::MainWindow *ui;
Fan x; // This doesn't work
Fan * x; // This doesn't either
int x; // This does work
};
#endif // MAINWINDOW_H
And here is the cpp file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "fan.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btOn_clicked()
{
ui->lblState->setText("Fan is on");
}
void MainWindow::on_btOff_clicked()
{
x.turnOff(); // This does not work of course
x->turnOff(); // Or this
ui->lblState->setText("Fan is off");
}
I already told the cpp file to include the Fan class from the fan.h file. If I create the object within the window constructor, it initializes fine but is not global. Also, there is no circular inclusion of header files. Fan class does not include mainwindow.
Perhaps I don't know how to search for it, but I've already done some research into it to no avail. Any help is appreciated.
Edit:
Here is the fan.cpp file
#include "fan.h"
Fan::Fan(){
speed = 0;
isOn = false;
}
void Fan::setSpeed(int s){
speed = s;
}
int Fan::getSpeed(){
return speed;
}
void Fan::turnOn(){
isOn = true;
speed = 1;
}
void Fan::turnOff(){
isOn = false;
speed = 0;
}
bool Fan::getState(){
return isOn;
}
And the fan.h file:
#ifndef FAN_H
#define FAN_H
class Fan
{
private:
int speed;
bool isOn;
public:
Fan();
void setSpeed(int);
void turnOn();
void turnOff();
int getSpeed();
bool getState();
};
#endif // FAN_H
You forget to include or declare the class Fan in your Header File. If you use
Fan * x;
You could use
class Fan;
as a forward declaration at the beginning of your Header File. The Compiler only need to know that there is a class called Fan but inside the Header you only use a pointer. Butt don't forget to #include the real file in your CPP file.
If you use
Fan x;
you have to #include the Fan.h in your Header-File
Related
So, I have the source code for a training. Where I want to do operation with QGraphicsView named pp in the own class ProcessPicture.
I would ask you, is it possible to put the QGraphicsView object to the method of own class? If yes, please tell me how or lead me on answer.
For a detailed description after releasing button will done the on_processPic_pushButton_released() where is called the method of pp object. This method take a ui->graphicsview as argument. This argument will used in the pp.drawrectangle(ui->graphicsview).
The code is without error or warning, only it is not draw the rectangle to the ui->graphicsview. When I take a source code from pp.drawrectangle() and try it, in the on_processPic_pushButton_released() all is fine. So I think that i miss some knowledge.
Lets look on my source code.
processpicture.h
#ifndef PROCESSPICTURE_H
#define PROCESSPICTURE_H
#include "QString"
#include "QPicture"
#include "QGraphicsView"
class ProcessPicture
{
public:
ProcessPicture();
void draw(QGraphicsView out);
void draw_rectangle(QGraphicsView out);
private:
QString path = "***/Untitled.bmp";
QImage img;
};
#endif // PROCESSPICTURE_H
processpicture.cpp
#include "processpicture.h"
#include "QGraphicsScene"
#include "QGraphicsPixmapItem"
ProcessPicture::ProcessPicture()
{
img.load(path);
}
void ProcessPicture::draw_rectangle(QGraphicsView out){
//QGraphicsScene* scene = new QGraphicsScene();
QGraphicsScene scene;
QRect rect;
rect.setRect(10,10,10,10);
scene.addRect(rect);
out.setScene(&scene);
out.show();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "processpicture.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
ProcessPicture *pp;
//pp = new ProcessPicture;
~MainWindow();
private:
private slots:
void on_processPic_pushButton_released();
private:
Ui::MainWindow *ui;
bool event(QEvent *event);
};
#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);
pp = new ProcessPicture;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_processPic_pushButton_released()
{
//pp->draw(ui->graphicsView);
pp->draw_rectangle(ui->graphicsView);
}
For every non-toxic answer I thank.
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.
Hi i have 3 classes that i want to use. but i dont want to create object of one class more than once. I directly want to use the object (in third class) of one class declared and initialized in second class.
To understand the problem please focus on NetworkConnection members and class defined in example below.
Class Mainwindow header
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "secondscreen.h"
#include "networkconnection.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
NetworkConnection *NetworkConnectionObject;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
SecondScreen* SecondScreenObject;
};
#endif // MAINWINDOW_H
Class Main Window cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QMessageBox"
#include "networkconnection.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
NetworkConnectionObject = new NetworkConnection();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
int Error = NetworkConnectionObject->Connect(Username,Password);
///////////////
// This Works
//////////////
NetworkConnectionObject->LogInToken = "";
}
Class NetworkConnection Header
#ifndef NETWORKCONNECTION_H
#define NETWORKCONNECTION_H
#include <QString>
class NetworkConnection
{
public:
NetworkConnection();
int Connect(QString Username, QString Passwd);
QString LogInToken;
};
#endif // NETWORKCONNECTION_H
Now i want to use Networkclassobject directly in SeconScreenclass so that i can access LogInToken Member of MainWindowInstance.
#include "secondscreen.h"
#include "ui_secondscreen.h"
#include "mainwindow.cpp"
SecondScreen::SecondScreen(QWidget *parent) :
QDialog(parent),
ui(new Ui::SecondScreen)
{
ui->setupUi(this);
///////////////
// This doesnot work
//////////////
MainWindow::NetworkConnectionObject->LogInToken = "";
}
SecondScreen::~SecondScreen()
{
delete ui;
}
However, when i try this compiler says
Invalid use of non-static data member "MainWindow::NetworkConnectionObject" Problem is i dont want to declare it static. Is there any way to do it.
Without seeing secondscreen.h I can't say for sure but MainWindow::NetworkConnectionObject" doesn't reference a specific instance of MainWindow class, you must reference a specific instance to modify.
If in your SecondScreen header you have something like
class SecondScreen {
// . . .
MainWindow window;
// . . .
}
then in your constructor for SecondScreen you must use the initialized instance of MainWindow, i.e.
SecondScreen::SecondScreen(QWidget* parent) : QDialog(parent) {
window.NetworkConnectionObject->LogInToken = "";
}
#include "main.h"
#include "ui_main.h"
Main::Main(QWidget *parent):
QMainWindow(parent),
ui(new Ui::Main)
{
ui->setupUi(this);
}
Main::~Main()
{
delete ui;
}
I have this header file main for Qt in which part should I create global variable
You can make use of extern variables. declare and define those variables
in any .h or .cpp file and you can use them in other files using extern
keyword and that variable name.
e.g. in my main.cpp I have Qstring A = "xyz";
suppose I have mainwindow.h and mainwindow.cpp
in mainwindow.h
extern Qstring A;
you will get the value of A in mainwindow.
If you really want to do that then you need to implement a Singleton class.
And after that you can use it like this:
class Common final
{
public:
Common& instance() // In the cpp.
{
static Common common;
return common;
}
static int value() // In the cpp.
{
return 11;
}
static std::string text() // In the cpp.
{
return "desired text";
}
private:
Common() // In the cpp.
{
}
};
Or just add some variables in a separate header file, but with OO I think it's better inside a class (or at least inside a namespace).
To use the variable of file in another file...
1.in the header file make a variable publically...
2.include that header file in another .cpp file...
3.to use the variable of that file make an object of the file and by using member operator...
//Main header file...
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "a.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
int i=10;
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//in cpp file og
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
a obj;
obj.setModal(true);
obj.exec();
}
//the cpp file in which you want to use the variable...
//here make an object of the header file an use member operator...
#include "a.h"
#include "ui_a.h"
#include "mainwindow.h"
a::a(QWidget *parent) :
QDialog(parent),
ui(new Ui::a)
{
ui->setupUi(this);
}
a::~a()
{
delete ui;
}
void a::on_pushButton_clicked()
{
MainWindow obj;
qDebug()<<obj.i;
}
I wanted to create a window from a mainwindow, and send it a pointer to my main window. I did it one time, and i would do it again, but the second time, I always have this error at compilation "no appropriate default constructor available"
The main window:
#include "costsimulator.h"
#include "ui_costsimulator.h"
#include "stonepricewindow.h"
CostSimulator::CostSimulator(AionEnhancingSimulator *parent) : ui(new Ui::CostSimulator)
{
ui->setupUi(this);
parentPtr = parent;
stonePrice = createStonePrice();
connect(ui->aionEnhancingSimulator, SIGNAL(clicked()), this, SLOT(showAionEnhancingSimulatorWindow()));
connect(ui->stonePriceButton, SIGNAL(clicked()), this, SLOT(showStonePriceWindow()));
}
CostSimulator::~CostSimulator()
{
delete ui;
}
void CostSimulator::showAionEnhancingSimulatorWindow()
{
this->hide();
parentPtr->show();
}
QStringList *createStonePrice()
{
QStringList *tmp = new QStringList();
tmp->push_back(QString("80-30000000"));
return (tmp);
}
void CostSimulator::showStonePriceWindow()
{
StonePriceWindow *stonepricewindow = new StonePriceWindow(this);
stonepricewindow->show();
}
QStringList *CostSimulator::getStonePrice()
{
return (stonePrice);
}
and the header:
#ifndef COSTSIMULATOR_H
#define COSTSIMULATOR_H
#include <QDialog>
#include "aionenhancingsimulator.h"
namespace Ui {
class CostSimulator;
}
class CostSimulator : public QDialog
{
Q_OBJECT
public:
AionEnhancingSimulator *parentPtr;
explicit CostSimulator(AionEnhancingSimulator *parent);
~CostSimulator();
QStringList *stonePrice;
QStringList *createStonePrice();
QStringList *getStonePrice();
void showStonePriceWindow();
public slots:
void showAionEnhancingSimulatorWindow();
private:
Ui::CostSimulator *ui;
};
#endif // COSTSIMULATOR_H
and the window that cause the problem:
#include "stonepricewindow.h"
#include "ui_stonepricewindow.h"
#include <QStringListModel>
#include <QStandardItemModel>
#include <QtGui>
StonePriceWindow::StonePriceWindow(CostSimulator *parent) : ui(new Ui::StonePriceWindow)
{
ui->setupUi(this);
displayStonePriceList(parent);
}
StonePriceWindow::~StonePriceWindow()
{
delete ui;
}
void StonePriceWindow::displayStonePriceList(CostSimulator *parent)
{
// To do
}
the header
#ifndef STONEPRICEWINDOW_H
#define STONEPRICEWINDOW_H
#include <QDialog>
#include "costsimulator.h"
namespace Ui {
class StonePriceWindow;
}
class StonePriceWindow : public QDialog
{
Q_OBJECT
public:
explicit StonePriceWindow(CostSimulator *parent = 0);
~StonePriceWindow();
void displayStonePriceList(CostSimulator *parent);
private:
Ui::StonePriceWindow *ui;
};
#endif // STONEPRICEWINDOW_H
if I had this " StonePriceWindow() {}" to the header of StonePriceWindow, I have the following error: "multiple default constructors specified" and always the "no appropriate etc .."
Thanks for any help, I can't understand why.
Sorry, but I could not add a comment on the best answer..
I had a similar problem too, it appeared that there was a mismatch between the classname of the code I created and the dialogs' objectName property value in the Qt .ui file.
I opened the .ui file in QtDesigner, and changed the objectName property value to the classname I had used in my code. Afterwards compilation was going fine.
Try adding StonePriceWindow(){} and removing the default parameter for the other constructor.
When you write code like
StonePriceWindow x;
how does compiler know whether you call the parameterless constructor or another one with default value for parent?
You need to either remove the other one, or remove the default value from it.
I found the problem.
In the StonePrinceWindow.ui, there was an obsolete name of the UI, so the auto-generated ui_stonepricewindow keep the obsolete name (even after a clean) and the compiler never find the ctor.
The solution is to change the strings
#ifndef COSTSIMULATOR_H
#define COSTSIMULATOR_H
in either of the files costsimulator.h and ui_costsimulator.h
Qt places the same #ifndef #define expression in auto generated ui_costsimulator.h