If I define the function in mainwindow.cpp the function works, but when I define it in radiobuttons.cpp, and attempt to call it from mainwindow.cpp, the project won't compile.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
void build_radios(); //this function
~MainWindow();
};
#endif // MAINWINDOW_H
radiobuttons.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
void MainWindow::build_radios()
{
//... some code
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
void MainWindow::radio_buttons(); //error: C2761: 'void MainWindow::build_radios(void)' : member function redeclaration not allowed
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
radio_buttons();
}
That's not a definition, the compiler sees it as a declaration of a member function outside the class definition, which is illegal. Just remove that line. It shouldn't be there in the first place, it has no use.
In fact, move the actual definition from radiobuttons.cpp to mainwindow.cpp for consistency. Why declare a MainWindow member in a different implementation file?
but when I define it in radiobuttons.cpp...
Except that you don't define but re-declare it. (And even that's redundant since you have the header file of the class included in that particular file.) The error message says pretty much what the problem is:
member function redeclaration not allowed
When you declare the MainWindow class, you have the void build_radios(); declaration inside - that in itself is enough for declaring the method. In the .cpp file, it's sufficient to implement it only, i. e. provide a definition only - you already have a declaration, coming from declaration of the class in the header file.
(In fact, you also have a definition, but that's in the radiobuttons.cpp file - it should be in the mainwindow.cpp. Fit all the methods of a class into one implementation file, don't speread them across multiple files and classes and... and... and...)
Related
I have a Qt gui project and in the "mainwindow.cpp" file I have to define a function that I cannot declare under "mainwindow.h". But I want to call that function (func_sqrt) under MainWindow and show the result value of my func_sqrt in a label. For some reason I need to do that so. But I don't know how to connect that function to the gui objects. My code looks like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
QString input;
void func_sqrt(int x);
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
func_sqrt(2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showtext(QString txt)
{
ui->lbl_value->setText(txt);
}
void func_sqrt(int x)
{
int y;
y = x*x;
}
I added this part to the func_sqrt function, but it doesn't work:
MainWindow *w = new MainWindow;
w->showtext(QString::number(y));
First of all, your func_sqrt currently is a no-op. Next, internally it calculates a square yet its name says sqrt (short for square root), you might want to check whether the name is consistent with semantics. This is for the side notes.
If you need this function available outside of mainwindow.cpp, you can declare it in a separate header and include it everywhere as needed. Alternatively, you can declare it in every file it is used in, the linker will later resolve the actual implementation. For instance, in a file subordinatewindow.cpp:
void func_sqrt(int);
// ...
int x{42};
func_sqrt(x);
I am trying to write an application where I would have a generic dialog window and specific dialog windows that would inherit some basic functionalities from the generic one. I am not sure this is the best approach for this, but this is how I did it (The CGenericProject class was created from Dialog template in Qt Creator):
CGenericProject.h:
#include <QDialog>
namespace Ui {
class CGenericProject;
}
class CGenericProject : public QDialog
{
Q_OBJECT
public:
explicit CGenericProject(QWidget *parent = 0);
~CGenericProject();
protected:
Ui::CGenericProject *ui;
};
CGenericProject.cpp:
#include "cgenericproject.h"
#include "ui_cgenericproject.h"
CGenericProject::CGenericProject(QWidget *parent) :
QDialog(parent),
ui(new Ui::CGenericProject)
{
ui->setupUi(this);
}
CGenericProject::~CGenericProject()
{
delete ui;
}
CEisProject.h:
#include "cgenericproject.h"
class CEisProject : public CGenericProject
{
public:
CEisProject();
~CEisProject();
};
CEisProject.cpp:
#include "ceisproject.h"
CEisProject::CEisProject()
{
ui-> NO ACCESS
}
CEisProject::~CEisProject()
{
}
As you see in the CEisProject.cpp file, I have no access to the ui field inherited from CGenericProject, even though it is protected. I mean, I see ui itself, but I dont see its methods and members. Any other variable that I would define there, would be accessible. What's wrong? I would appreciate all help in this manner.
You have to add the line
#include "ui_cgenericproject.h"
to the CEisProject.cpp file.
The CGenericProject.h file is included in CEisProject.h, but CEisProject.h does not have access to CGenericProject.cpp. In the header of your base class you have a only forward declaration of Ui::CGenericProject, and you include its file in the .cpp. So CGenericProject.cpp knows the implementation of this class.
But CEisProject.cpp doesn't have access to that, so you have to include the file again in here.
NOTE
Your forward declaration is confusing, you should indent it properly. Also, add some comments to your code to add some clarity for who is reading it, you're using two different classes with the same name.
This is about a Qt 5.3.2 project buildt using CMake.
I have designed a QMainWindow using the Qt Designer, leading
to main.ui.
CMakeLists.txt (the almost complete thing may be
found here where I already posted it for a different question:
Linking and UIC order in a CMake Qt project )
already takes care of calling UIC so I have my hands on ui_main.h.
ui_main.h offers the class Ui::MainWindow with the plain form information
where all the buttons and stuff should be and the method *void setupUi(QMainWindow MainWindow).
Now my workflow (is it even a feasible one?) goes like this:
I build a totally new header file Form_main.h:
// Form_main.h
[..]
class Form_main : public MainWindow, public QMainWindow
{
Q_OBJECT
privat slots:
void on_some_event();
[..]
};
The class uses said auto-generated MainWindow::setupUi(this) to 'get in shape' and QMainWindow to be, well, a QMainWindow with all that stands for.
But now I am in a dilemma: Either I remove the Q_OBJECT macro call leading to connect(..) no longer recognizing that Form_main has signal slots, or
I keep the Q_OBJECT leading to the infamous
undefined reference to `vtable for display::Form_main'
error while linking the project.
Now, there have been, in fact, people with similar issues.
Naming some links:
http://michael-stengel.com/blog/?p=103
Qt Linker Error: "undefined reference to vtable"
Undefined reference to vtable... Q_OBJECT macro
Qt vtable error
A hint I got from the last one: "MOC must generate code for ui_main.h and the generated code must be compiled and linked."
In any case, these answers all seem to boil down to 'running qmake again'. Well, I use CMake all the way wanting my project to configure and compile after exactly
cmake .
make
What I did try was deleting everything in and below the build directory
(including every auto-generated file) and then running cmake . && make;.
Sadly that did not help. I am afraid this is my second noob question today... would you bear with me once more?
=== AFTER TRYING GREENWAYS ANSWER I PROVIDE MORE DETAILS. ===
Here is the autogenerated ui_main.h
/********************************************************************************
** Form generated from reading UI file 'main.ui'
**
** Created by: Qt User Interface Compiler version 5.3.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAIN_H
#define UI_MAIN_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
[.. more Widget Includes ..]
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QAction *action_exit;
[.. more sub widgets like that .. ]
void setupUi(QMainWindow *MainWindow)
{
[ .. Setting up the form. Harmless code. .. ]
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
[ .. completely harmless .. ]
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAIN_H
Reading all this and incorporating your post right now I am at
// form_main.h
#ifndef MHK_FORM_MAIN_H
#define MHK_FORM_MAIN_H
#include <QMainWindow>
#include "ui_main.h"
[..]
namespace Ui { class MainWindow; }
namespace display
{
class Form_main : public QMainWindow
{
Q_OBJECT
private:
ostream* stdout;
ostream* stderr;
Ui::MainWindow* uiMainWindow;
/** Called by the constructor. Sets up event connections and other
* preliminary stuff the qt Designer is overtasked with. */
void setup_form();
[..]
public:
explicit Form_main(QWidget* parent = 0);
~Form_main();
private slots:
void exit_program();
};
}
#endif
And my cpp
// form_main.cpp
#include "ui_main.h"
#include "form_main.h"
[..]
using namespace Ui;
namespace display
{
void Form_main::setup_form()
{
QObject::connect(uiMainWindow->action_exit, SIGNAL(triggered()), this, SLOT(exit_program()));
[..]
}
Form_main::Form_main(QWidget* parent) : QMainWindow(parent)
{
uiMainWindow = new Ui::MainWindow();
uiMainWindow->setupUi(this);
[..]
#if defined(Q_OS_SYMBIAN)
this->showMaximized();
#else
this->show();
#endif
}
Form_main::~Form_main()
{
delete uiMainWindow;
}
[..]
Form_main::exit_program()
{
this->close();
(*stdout) << "Thanks for playing " << getProgramName() << endl;
}
}
Ok. I see (partly) the problem. Just create a widget class like this:
.h
#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:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
This is how the QtCreator creates ui-Widgets. "ui_MainWindow.h" is your generated .h file.
Thanks for all your help! However, the problem was in CMakeLists.txt after all. The comment of Chris Morlier on Undefined reference to vtable pointed me to the solution.
The pertinent passage goes:
For Qt users: you can get this same error if you forget to moc a header
I simply had to add the header form_main.h into this line:
QT5_WRAP_CPP(qt_H_MOC ${qt_H} "${DIR_SRC}/include/form_main.h")
I have some functions in delphi dll, and I want to load them (using QtLibrary) at once.
Can I store that functions in global variables to use it? I tried to declare global function pointer in .h file and resolve them in main file, but got error "multiple definition"
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qlibrary.h>
#include <QDebug>
#include "mapwidget.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QString path = "map_dll.dll";
if (QLibrary::isLibrary(path)) {
lib = new QLibrary(path);
lib->load();
if (!lib->isLoaded()) {
qDebug() << lib->errorString();
} else {
nearestWell = (void( *)(double x,
double y,
double &wellX,
double &wellY))
lib->resolve("nearestWell");
}
}
}
void MainWindow::on_pushButton_2_clicked()
{
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLibrary>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QLibrary *lib;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mapwidget.h
#ifndef MAPWIDGET_H
#define MAPWIDGET_H
#include <QWidget>
#include <QPainter>
typedef void (*NearestWellFunc) (double x, double y, double &wellX,
double &wellY);
extern NearestWellFunc nearestWell;
....
#endif // MAPWIDGET_H
error message:
debug/mainwindow.o: In function `ZN10MainWindow21on_pushButton_clickedEv':
C:\nipi\APT\map_qt\build-MIG-Desktop_Qt_5_1_0_MinGW_32bit-Debug/../MIG/mainwindow.cpp:33: undefined reference to `nearestWell'
C:\nipi\APT\map_qt\build-MIG-Desktop_Qt_5_1_0_MinGW_32bit-Debug/../MIG/mainwindow.cpp:40: undefined reference to `nearestWell'
C:\nipi\APT\map_qt\build-MIG-Desktop_Qt_5_1_0_MinGW_32bit-Debug/../MIG/mainwindow.cpp:54: undefined reference to `nearestWell'
Makefile.Debug:84: recipe for target 'debug/MIG.exe' failed
mingw32-make[1]: Leaving directory 'C:/nipi/APT/map_qt/build- MIG-Desktop_Qt_5_1_0_MinGW_32bit-Debug'
makefile:34: recipe for target 'debug' failed
C:\nipi\APT\map_qt\build-MIG-Desktop_Qt_5_1_0_MinGW_32bit-Debug/../MIG/mainwindow.cpp:63: undefined reference to `nearestWell'
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [debug/MIG.exe] Error 1
mingw32-make: *** [debug] Error 2
This error:
undefined reference to `nearestWell'
Is the compiler saying "I know that there is a thing called nearestWell, but I don't know where it is stored (because it hasn't been defined)"
This line:
extern NearestWellFunc nearestWell;
Says to the compiler "somewhere else there will be a NearestWellFunc called nearestWell".
This is a declaration - it is telling the compiler that there will be a variable called nearestWell somewhere later.
It needs to be paired with a definition that tells the compiler to set aside some space for the variable. In this case, it would look something like:
NearestWellFunc nearestWell = /* whatever the initial value should be */
Remember, you can only define things once, or the compiler will get confused. This is why you need to put the declaration inside a .cpp file rather than the .h file - if you put the definition in the header file, each .cpp file that includes that header will include the definition, which is what is causing the multiple definition error.
Looking at your example structure, I would put the definition in mainwindow.cpp.
You can declare the variables in a header file, but you can't define them.
For example, declaring a variable as extern in a header file is fine. You probably define them instead. Add the extern keyword to your declarations in the header file, and add definitions in a source file.
I am running QT Creator on a Linux Ubuntu 9.10 machine. I just got started with QT Creator, and I was going through the tutorials when this error popped up while I was trying to build my project: "ISO C++ forbids declaration of 'QPushButton' with no type". This problem appears in my header file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QWidget>
namespace Ui
{
class MainWindow;
}
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void addContact();
void submitContact();
void cancel();
private:
Ui::MainWindow *ui;
QPushButton *addButton;
QPushButton *submitButton;
QPushButton *cancelButton;
QLineEdit *nameLine;
QTextEdit *addressText;
QMap<QString, QString> contacts;
QString oldName;
QString oldAddress;
};
#endif // MAINWINDOW_H
I think you are simply missing the appropriate header file. Can you try
#include <QtGui/QtGui>
instead, or if you prefer
#include <QtGui/QPushButton>
Actually, forward declaration would be enough, instead of the include:
class QPushButton;
Always prefer forward declarations in headers, and do the include in the .cpp
(faster and less recompilations in larger projects).
You are missing this:
#include <QtGui>
You might also want to check the .pro file.
Do you have an entry like "QT = ..." somewhere? If so, try changing that to "QT += ...". Qt's Core and GUI module are default settings for the QT variable, but CAN be overwritten, which will lead to compiler and/or linker errors.