I've encountered an error which I cannot seem to find a solution to anywhere else.
The error occurs when I'm trying to declare an instance of the "EncodeWindow" class.The compiler is giving errors C2143,C4430 and C2238. I am simply trying to give the "MainWindow" class an instance of "EncodeWindow".
File mainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QLabel>
#include "Image.h"
#include "encodewindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
/*Check whether a given file path is valid*/
bool CheckFilePath(QString);
/*Sets UI widgets*/
void setOriginalImage_Label(const char*);
void setEncodedImage_Label(const char*);
void setDebug_TextBox(QString);
/*Saves all information about current encoding/decoding*/
void saveFile();
private slots:
void on_Encode_Button_clicked();
void on_Reset_Button_clicked();
void on_Save_Button_clicked();
void on_AddEncodeImage_Debug_Button_clicked();
void on_AddImage_Button_clicked();
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
EncodeWindow *CurrentEncodeWindow = new EncodeWindow; //ERROR HERE!! C2143
int fileNumber = 0;
};
#endif // MAINWINDOW_H
File encodeWindow.h:
#ifndef ENCODEWINDOW_H
#define ENCODEWINDOW_H
#include <QMainWindow>
#include "mainwindow.h"
namespace Ui {
class EncodeWindow;
}
class EncodeWindow : public QMainWindow
{
Q_OBJECT
public:
explicit EncodeWindow(QWidget *parent = 0);
~EncodeWindow();
/*Get filepaths from 'result' object (For access to filepaths without 'encode' Window)*/
const char* getOriginalFilePath();
const char* getEncodeFilePath();
const char* getSaveFilePath();
bool checkUI(const char*,const char*,const char*,bool*);
bool CheckFilePath(const char*);
std::string readInText(const char*);
private slots:
void on_RedChannel_CheckBox_clicked(bool);
void on_GreenChannel_CheckBox_clicked(bool);
void on_BlueChannel_CheckBox_clicked(bool);
void on_AlphaChannel_CheckBox_clicked(bool);
void on_BitDepth_Slider_sliderMoved(int);
void on_BitDepth_SpinBox_valueChanged(int);
void on_Encode_Button_clicked();
private:
Ui::EncodeWindow *ui;
Encoded result; //Enocoded object (child of Image class)
};
#endif // ENCODEWINDOW_H
Any help would be great. The code was done in Qt for an image steganography project.
Thanks.
You have circular includes. "mainwindow.h" includes "encodewindow.h" and "encodewindow.h" includes "mainwindow.h". The include guards stop the cycle, but the class definitions for whichever header is included first won't be complete in the second include file, which will result in your errors.
In the snippet above, there's nothing that I see in encodewindow.h that uses anything in mainwindow.h, so just remove the include of mainwindow.h from encodewindow.h.
Related
today I wanted to start diving in into QT by doing the official notepad tutorial. It is said that the header will be generated automatically to this:
#include <QMainWindow>
namespace Ui {
class Notepad;
}
class Notepad : public QMainWindow
{
Q_OBJECT
public:
explicit Notepad(QWidget *parent = 0);
~Notepad();
private slots:
void on_actionNew_triggered();
void on_actionOpen_triggered();
void on_actionSave_triggered();
void on_actionSave_as_triggered();
void on_actionPrint_triggered();
void on_actionExit_triggered();
void on_actionCopy_triggered();
void on_actionCut_triggered();
void on_actionPaste_triggered();
void on_actionUndo_triggered();
void on_actionRedo_triggered();
void on_actionFont_triggered();
void on_actionBold_triggered();
void on_actionUnderline_triggered();
void on_actionItalic_triggered();
void on_actionAbout_triggered();
private:
Ui::Notepad *ui;
QString currentFile;
};
But after saving and even restartin qtcreator I'm getting this:
#ifndef NOTEPAD_H
#define NOTEPAD_H
#include <QMainWindow>
namespace Ui {
class Notepad;
}
class Notepad : public QMainWindow
{
Q_OBJECT
public:
explicit Notepad(QWidget *parent = nullptr);
~Notepad();
private:
Ui::Notepad *ui;
};
#endif // NOTEPAD_H
Is there any information file about configuration I could provide to allow you to help me? Or anything in the settings?
As far as I can see there is some problem with the Design .ui tool.
I have four files:
mainwindow.h
#pragma once // MAINWINDOW_H
#include <QMainWindow>
#include <QApplication>
#include "maincontent.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setStatusBarMessage(QString message);
signals:
public slots:
void exit();
private:
void setMenuBar();
MainContent* content;
};
maincontent.h
#pragma once // MAINCONTENT_H
#include "statistic.h"
#include "information.h"
#include <QWidget>
#include <QHBoxLayout>
class MainContent : public QWidget
{
Q_OBJECT
public:
explicit MainContent(QWidget *parent = nullptr);
signals:
public slots:
private:
QHBoxLayout* layout;
Statistic* statistic;
Information* financFlow;
};
information.h
#pragma once // INFORMATION_H
#include <QPushButton>
#include <QWidget>
//#include "mainwindow.h" //error
class Information : public QWidget
{
Q_OBJECT
public:
explicit Information(QWidget *parent = nullptr);
signals:
public slots:
private:
QPushButton* button;
};
statistic.h
#pragma once // STATISTIC_H
#include <QWidget>
#include <QHBoxLayout>
#include <QListView>
class Statistic : public QWidget
{
Q_OBJECT
public:
explicit Statistic(QWidget *parent = nullptr);
signals:
public slots:
private:
QListView* listView;
};
Now I will use the MainWindow::setStatusBarMessagemethod from the Information class.
But when I include the MainWindow in the Information class: #include "mainwindow.h"
I become the error: MainContent does not name a type in line 22 in mainwindow.h
First I don't know why the compiler can't find MainContent bacause in MainWindow I included the "maincontent.h", does the preprocessor only include "mainwindow.h" but not the "maincontent.h" in the "mainwindow.h"?
I see that with #include "mainwindow.h" a recursion arise but that shouldn't be a problem because of #pragma once or?
Next I tried to include the "mainwindow.h" in the information.cpp file but then I have the problem that I everytime give the MainWindow object by parameter and can't hold a MainWindow in my class
My main problem is that the MainWindow has a statusBar Object and I will set the statusBar message from everywhere. How can I do this, exist a Pattern or someting for that?
How can I solve this Problem or where I make a thinking mistake?
Thanks for your help.
You should use forward declaration for your included classes. Since pointers itself do not need to know a fully declared class (pointer size is always the same) you can easily get around this:
In header File instead of include the class just declare it:
#include <QMainWindow>
#include <QApplication>
//#include "maincontent.h" // REmove these
class MainContent;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setStatusBarMessage(QString message);
signals:
public slots:
void exit();
private:
void setMenuBar();
MainContent* content;
};
In cpp file now include the header again. Do this for all includes only having a pointer to given class.
As mentioned by #dempzorz removing the circular dependency is always prefered, but not always possible.
You have a circular dependency. You can't have information.h include mainwindow.h and also have mainwindow.h include information.h. You should design dependencies in a hierarchy, where items lower in the tree do not include items higher in the tree.
You should have a look at this link to maybe give you a better understanding of how to structure your objects:
https://en.wikipedia.org/wiki/Circular_dependency
i am developing a breakout game using C++ in qt creator. i am getting an error saying "Game has not been declared". i have declared it using the game.h the error is in the header file. i cannot figure out where the problem is. please, any help would be highly appriciated.
#ifndef BALL_H
#define BALL_H
#include<QCloseEvent>
#include <QGraphicsRectItem>
#include "game.h" //i have declared it here.
class Ball: public QObject, public QGraphicsRectItem{
Q_OBJECT
public:
// constructors
Ball(QGraphicsItem* parent=NULL);
QTimer *runTimer;
// public methods
double getCenterX();
public slots:
// public slots
void move();
void start_timer();
void stop_timer();
void call_game_fuction(Game *gm); //here i am getting the error(Game)
private:
// private attributes
double xVelocity;
double yVelocity;
int counter = 0;
// private methods
void resetState();
bool reverseVelocityIfOutOfBounds();
void handlePaddleCollision();
void handleBlockCollision();
};
#endif // BALL_H
and this is the fuction of the CPP file
Game *obj1 =new Game();
game_function *obj2 = new game_function();
void Ball::call_game_fuction(Game *gm)
{
gm->set_background();
}
sir this is my game.h file
#ifndef GAME_H
#define GAME_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include "Ball.h"
#include "Paddle.h"
#include "Block.h"
#include<QPushButton>
class Game:public QGraphicsView{
Q_OBJECT
public:
// constructors
Game(QWidget* parent=0);
QPushButton *button;
QPushButton *button1;
// public methods
void start();
void createBlockCol(double x);
void creatBlockGrid();
void set_background();
void background_Gamewon();
void set_buttons();
QGraphicsScene* scene2;
// public attributes
QGraphicsScene* scene;
QGraphicsView* view;
private slots:
void startgame();
void stopgame();
private:
bool gameOver;
Ball *ball;
Paddle *pad;
Block *bl;
};
#endif // GAME_H
You have a cyclic dependency. Ball.h includes game.h, and game.h includes Ball.h. This is an impossible situation for the compiler to resolve, as neither one can be included before the other.
It appears that game.h does not need to #include "Ball.h". Instead, use a forward declaration:
class Ball;
That should be enough to compile game.h.
I have four classes at the moment. Client, ChatWindow, FunctionCall and MainWindow. What I ultimatly would want to do is not have FunctionCall class and have a virtual inheritance of Client in ChatWindow and MainWindow, but QT, or more specifically QObject doesn't allow this.
The reason I thought a virtual class would be good is to not create two different instances of a class, but rather have ChatWindow and MainWindow share the variables.
I've made a FunctionCall class that inherits Client, and I've created virtual inheritance between ChatWindow and MainWindow with FunctionCall
ChatWindow.h
#ifndef CHATWINDOW_H
#define CHATWINDOW_H
#include <QWidget>
#include "functioncall.h"
namespace Ui {
class ChatWindow;
}
class ChatWindow : public QMainWindow, public virtual FunctionCall
{
Q_OBJECT
public:
explicit ChatWindow(QWidget *parent = 0);
~ChatWindow();
private slots:
void on_sendButton_clicked();
private:
Ui::ChatWindow *ui;
};
#endif // CHATWINDOW_H
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "functioncall.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow, public virtual FunctionCall
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_connectButton_clicked();
private:
Ui::MainWindow *ui;
protected:
void something();
};
#endif // MAINWINDOW_H
FunctionCall.h
#ifndef FUNCTIONCALL_H
#define FUNCTIONCALL_H
#include "client.h"
class FunctionCall : public Client
{
public:
FunctionCall();
};
#endif // FUNCTIONCALL_H
Client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <QApplication>
#include <QWidget>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QTcpSocket>
#include <QString>
#include <QTcpServer>
#include <QStringList>
#include <QNetworkSession>
#include <QDataStream>
#include <QGridLayout>
#include <QMainWindow>
class Client : public QDialog
{
Q_OBJECT
public:
Client(QWidget *parent = 0);
public slots:
void read();
void displayError(QAbstractSocket::SocketError socketError);
void sessionOpened();
void connectedSocket();
void disconnectedSocket();
void pushToSocket(
quint8 registerForm,
QString registerUsername,
QString registerPassword,
QString username,
QString text
);
QString readFromSocket();
void saveToFile(std::string fileName, QString text);
public:
QTcpSocket *tcpSocket;
quint16 blockSize;
QNetworkSession *networkSession;
QTcpServer *tcpServer;
struct HeaderFile {
quint8 registerForm = 2;
QString registerUsername;
QString registerPassword;
QString username;
QString text;
};
public:
QStringList *hostCombo;
void send(QString username, QString text);
void loginRegisterConnect(QString host, int port, QString username, QString password);
friend QDataStream & operator<<(QDataStream& str, const HeaderFile & data) {
str << data.registerForm << data.registerUsername << data.registerPassword << data.username << data.text;
return str;
}
friend QDataStream & operator>>(QDataStream& str, HeaderFile & data) {
str >> data.registerForm >> data.registerUsername >> data.registerPassword >> data.username >> data.text;
return str;
}
};
#endif // CLIENT_H
Problem is I'm getting an error, probably because the Client class inherits QDialog.
I was wondering if it was possible only to inherit from Client, and not what Client also inherits, basically I want to use the functions in the Client class. But nothing it inherits from QDialog.
It doesn't compile here is the error:
C:\\main.cpp:9: error: C2385: ambiguous access of 'show'
could be the 'show' in base 'QWidget'
or could be the 'show' in base 'QWidget'
Solved my issue:
I basically made a singleton of the Client class, and created instances of that.
No, because that would violate the type equivalency (Liskov Substitution Principle). Basically it means that since you inherit from Client every FunctionCall object will also be a Client object and since every Client object has to be a QDialog object it follows that the FunctionCall object has to be a QDialog object.
Also what you've seem to be victim of here is that you use multiple inheritance and the same (non-virtual) base appears twice in the inheritance tree. You probably should think twice or thrice about this: is this really the right design? is this really what you want? Note that the different occations of QWidget in the inheritance tree are different (sub) objects.
Qt can't see a signal that exists.
I have a main window that opens up a child window, and the connect statement for that works absolutely fine:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "addstaffform.h"
#include "stafflist.h"
#include "editstaffwindow.h"
#include <QDialog>
#include <QString>
#include <QList>
#include "person.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_btn_add_clicked();
void refreshStaffList();
void receiveData(Person& newPerson);
void receiveEditedPerson(Person &editedPerson, int index);
void updateDeleteEnabled();
void updateEditEnabled();
void on_btn_delete_staff_clicked();
void on_btn_staff_edit_clicked();
private:
Ui::MainWindow *ui;
QString s;
QMainWindow *newWin;
QMainWindow *editStaffWin;
StaffList *m_staffList;
QList<Person> m_personList;
Person m_person;
};
#endif // MAINWINDOW_H
The method in mainwindow.cpp that works with no problem:
void MainWindow::on_btn_add_clicked()
{
//Open the add staff window, which is a form
newWin = new AddStaffWindow(this);
//connect the signal from the new form to the slot in this window to receive the person object
connect(newWin, SIGNAL(sendData(Person&)), this, SLOT(receiveData(Person&)));
newWin->show();
}
Signal in addstaffwindow.h (the instantiation of newWin)
signals:
void sendData(Person &p);
Now, in the edit form (editStaffWin), I have the signal, and I've made sure that Q_OBJECT definitely IS there, cleaned, run QMake and build several times, but it doesn't think that the signal exists.
editstaffwindow.h
signals:
void sendPerson(Person &, int index);
So in the mainwindow.cpp for editing, sendPerson(Person &, int) doesn't show up:
void MainWindow::on_btn_staff_edit_clicked()
{
//Get the index of the widget
int index = ui->lst_staff->currentRow();
int size = ui->lst_staff->count();
if (index > -1 && index <= size)
{
//get from staff list
m_person = m_staffList->getStaffAt(index);
editStaffWin = new EditStaffWindow(this, m_person, index);
connect(editStaffWin, SIGNAL(sendPerson(Person &, int)), this, SLOT(receiveEditedPerson(Person&,int)));
editStaffWin->show();
}
}
Any ideas why? I'm not doing anything different for either of them.
EDIT: full EditStaffWindow header:
#ifndef EDITSTAFFWINDOW_H
#define EDITSTAFFWINDOW_H
#include <QMainWindow>
#include "mainwindow.h"
#include "person.h"
#include <QObject>
namespace Ui {
class EditStaffWindow;
}
class EditStaffWindow : public QMainWindow
{
Q_OBJECT
public:
explicit EditStaffWindow(QWidget *parent, Person &p, int index);
~EditStaffWindow();
signals:
void sendPerson(Person &, int index);
private:
Ui::EditStaffWindow *ui;
Person m_person;
int m_index;
public slots:
void showData(Person &p, int index);
private slots:
void on_btn_save_clicked();
void on_btn_cancel_clicked();
};
#endif // EDITSTAFFWINDOW_H
It seems that not using the code autocompletion is probably part of the answer, as I have to manually type the signal
connect(editStaffWin, SIGNAL(sendPerson(Person &, int)), this, SLOT(receiveEditedPerson(Person&,int)));
Running clean, qmake, build all may have been part of it as well. What could have also caused a problem was how I was writing the signal for the connect statement, but looking back, it's the same.
What I did do, though, was remove the int declarations from the sendPerson signal, clean, build, then put them back, and it worked.
Apart from that, I'm not sure what caused it not to work.