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
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.
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 = "";
}
I have a simple QDialog that shows a QLabel in black text. I'd like for the QLabel's text to turn red when I press the a key. I am using the designer to make the dialog. Here is my code:
myDialog.h
#include <QDialog>
#include <QWidget>
namespace Ui {
class myDialog;
}
class myDialog : public QDialog
{
Q_OBJECT
public:
explicit myDialog(QWidget* parent = 0);
~myDialog();
private:
Ui::myDialog* ui;
protected:
void keyPressEvent(QKeyEvent* event);
};
myDialog.cpp
#include "myDialog.h"
#include "ui_myDialog.h"
#include <QKeyEvent>
myDialog::myDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::myDialog)
{
ui->setupUi(this);
}
void myDialog::eventPressEvent(QKeyEvent* event)
{
if (event->key()==Qt::Key_A){
Ui_myDialog::label1->setStyleSheet(QStringLiteral("QLabel{color: rgb(170, 0, 0);}"));
} else {
qDebug << "FAIL";
}
}
myDialog::~myDialog()
{
delete ui;
}
ui_mydialog.h
/********************************************************************************
** Form generated from reading UI file 'about.ui'
** Created by: Qt User Interface Compiler version 5.5.0
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MYDIALOG_H
#define UI_MYDIALOG_H
...<snip>...
QT_BEGIN_NAMESPACE
class Ui_myDialog
{
public:
QLabel *label1;
void setupUi(QDialog *myDialog)
{
...<snip>...
label1 = new QLabel(myDialog);
label1->setObjectName(QStringLiteral("label1"));
label1->setGeometry(QRect(50, 333, 16, 20));
label1->setFont(font);
label1->setAlignment(Qt::AlignCenter);
...<snip>...
} // setupUi
...<snip>...
namespace Ui {
class myDialog: public Ui_myDialog {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MYDIALOG_H
So, here's the issue. When I build the project, a file called ui_mydialog.h gets created and is generated in the build folder. This file even says it was auto-generated by the Qt User Interface Compiler. When I try to change the stylesheet of label1 (which is declared in ui_mydialog.h) in myDialog.cpp using the line:
Ui_myDialog::label1->setStyleSheet(QStringLiteral("QLabel{color: rgb(170, 0, 0);}"));
...I get an error that says error: invalid use of non-static data member 'Ui_myDialog::label1'. This is where I'm stuck. How would I go about correctly passing label1 into the void myDialog::eventPressEvent(QKeyEvent* event) member function and modifying it?
Any help would be appreciated.
Using Ui_myDialog:: on a non-static member is incorrect.
You need to replace
Ui_myDialog::label1->setStyleSheet(QStringLiteral("QLabel{color: rgb(170, 0, 0);}"));
with
ui->label1->setStyleSheet(QStringLiteral("QLabel{color: rgb(170, 0, 0);}"));
You don't need new Ui::myDialog in 'myDialog.cpp'.
1) myDialog.h
Add #include "ui_mydialog.h"
Change Ui::myDialog* ui; to Ui::myDialog ui;
2) myDialog.cpp
Remove ui(new Ui::myDialog) in constructor.
And, then you can use ui.label1->......
I have a Qt GUI application that opens a dialog when I go to Help > About. However, if I go to Help > About again, another dialog pops up. I'm trying to get it so that the already opened About dialog is the only one that can be open (i.e. no additional About dialogs allowed). I feel like this should be simple, but I keep getting a Segmentation Fault. Here's my code:
myApp.h
#ifndef MYAPP_H
#define MYAPP_H
#include <QMainWindow>
#include "about.h"
namespace Ui {
class MyApp;
}
class MyApp : public QMainWindow // inherit all public parts of QMainWindow
{
Q_OBJECT
public:
explicit MyApp(QWidget* parent = 0);
~MyApp();
private slots:
void on_actionAbout_triggered();
private:
Ui::MyApp* ui;
About* aboutDialog;
};
#endif // MYAPP_H
MyApp.cpp
#include "MyApp.h"
#include "ui_MyApp.h"
#include "about.h"
MyApp::MyApp(QWidget* parent) :
QMainWindow(parent),
ui(new Ui::MyApp)
{
ui->setupUi(this);
}
MyApp::~MyApp()
{
delete ui;
}
void MyApp::on_actionAbout_triggered()
{
if (!aboutDialog) {
aboutDialog = new About(this); // create new window
}
aboutDialog->show();
aboutDialog->activateWindow();
}
about.h
#ifndef ABOUT_H
#define ABOUT_H
#include <QDialog>
namespace Ui {
class About;
}
class About : public QDialog
{
Q_OBJECT
public:
explicit About(QWidget* parent = 0);
~About();
private:
Ui::About* ui;
};
#endif // ABOUT_H
about.cpp
#include "about.h"
#include "ui_about.h"
About::About(QWidget* parent) :
QDialog(parent),
ui(new Ui::About)
{
ui->setupUi(this);
}
About::~About()
{
delete ui;
}
In MyApp.cpp, when I get rid of the if, it works. But clicking Help > About (actionAbout_triggered) multiple times will open a bunch of About windows. I just want 1. So I figured I'd put in an if statement that says, if the About dialog is already open, don't create another one and just make it the active window instead. I'm met with a Segmentation Fault. I know this means it's trying to access memory somewhere that it shouldn't be, but I don't know why.
Any help would be greatly appreciated.
The normal way of doing this is to have a modal dialog box for your About window. Something like this
void MyApp::on_actionAbout_triggered()
{
About dlg(this);
dlg.exec();
}
Regarding your question specifically, the problem is you did not initialize aboutDialog to anything in the MyApp constructor, so it is "undefined value" - probably not null.
Set aboutDialog to null in your MyApp constructor to solve your segfaults.
I count some entries and want to emit a message, when the user has many entries, since it will be confusing.
Nevertheless the other hand the user should have the option to disable this warning.
That's why I wanted to use a QErrorMessage.
But my QErrorMessage kept on appearing even when it should not (/when the checkbox is unchecked).
This is the shortest code I wrote:
void checkNumber(int const &n)
{
if(n > CriticalNumber)
{
QErrorMessage msg(this);
msg.showMessage("too much!");
}
}
Did I forget anything?
The funny thing is, after you once unchecked the checkbox, it is unchecked in every next call...
// edit:
This error happens even when the QErrorMessage is a member of my class and not initialised in every call.
// edit2:
By now I am pretty sure, that this error only occurs, when I use QString::arg. I did not use this in the example code, since I thought this would make no difference. So the example should look like this:
void showError(int const &n, QErrorMessage *msg)
{
msg->showMessage(tr("%1 is too big").arg(n));
}
showError() is called in the previous if-statement.
I solved this problem (specified in edit2).
The problem is, that the QErrorMessage saves all the QStringsthat should not be shown again.
Since my arg() creates nearly every time a new QStringthe QErrorMessageis shown each time it is changed.
Example:
QErrorMessage msg(this);
showError(1, msg);
showError(2, msg);
showError(1, msg);
The first showError(1, msg) will show the QErrorMessage.
If you uncheck the checkbox, showError(2, msg) will be shown (because a different QString is shown), but not showError(1, msg) (since the shown QString is the same as the first one.
I cannot reproduce your problem. What you should to is make checkNumber a member of a class, and do the same for your msg object.
Here is a working example:
mainwinodw.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QErrorMessage>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void showErrorMsg();
private:
Ui::MainWindow *ui;
QErrorMessage msg;
QTimer timer;
};
#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);
connect(&timer, SIGNAL(timeout()), this, SLOT(showErrorMsg()));
timer.start(3000); // we use a timer to show an error message
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showErrorMsg()
{
msg.showMessage("My message");
}