I cannot get rid of the error "Undefined reference to vtable" when compiling my Linux desktop application.
I did find the thread
Undefined reference to vtable
I have a
set(CMAKE_AUTOMOC ON)
in my CMakeLists.txt
but I receive
AutoMoc warning
---------------
"SRC:/QtGUI/BASIC/SimulatorWindowBasic.cpp"
includes the moc file "SimulatorWindowBasic.moc", but does not contain a Q_OBJECT, Q_GADGET, Q_GADGET_EXPORT, Q_NAMESPACE or Q_NAMESPACE_EXPORT macro.
despite that my definition contains
a Q_Object.
At the end of build, I receive the feared message
/usr/bin/ld: CMakeFiles/Basic_GUI.dir/Basic_GUI.cpp.o: in function `main':
/Myhome/main/BASIC/Basic_GUI.cpp:6: undefined reference to `SimulatorWindowBasic::SimulatorWindowBasic(int, char**, QWidget*)'
/usr/bin/ld: CMakeFiles/Basic_GUI.dir/Basic_GUI.cpp.o: in function `SimulatorWindowBasic::~SimulatorWindowBasic()':
What do I wrong?
Below I show my relevant sources.
(in my previous install using Qt5 and Ubuntu 20.04
I did not experience this issue. The present install uses Ubuntu 22.04 and Qt 6.4.2)
#ifndef SimulatorWindowBasic_H
#define SimulatorWindowBasic_H
#include <QMainWindow>
namespace Ui {
class SimulatorWindowBasic;
}
class SimulatorWindowBasic : public QMainWindow
{
Q_OBJECT
public:
explicit SimulatorWindowBasic(int argc, char **argv, QWidget *parent = 0);
virtual ~SimulatorWindowBasic();
protected:
Ui::SimulatorWindowBasic *ui;
};
#endif // SimulatorWindowBasic_H
and
#include "SimulatorWindowBasic.moc"
#include "SimulatorWindowBasic.h"
#include "uiSimulatorWindowBasic.h"
SimulatorWindowBasic::SimulatorWindowBasic(int argc, char **argv, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SimulatorWindowBasic)
{
ui->setupUi(this); // This creates the basic splitters
}
SimulatorWindowBasic::~SimulatorWindowBasic
{
}
You have to include "moc_SimulatorWindowBasic.cpp" because you want to have moc run on a header (and not on your source) as described in the cmake documentation
Related
https://www.dvratil.cz/2019/11/q-private-slot-with-new-connect-syntax/
#include <QPushButton>
#include <memory>
class MyButtonPrivate;
class MyButton : public QPushButton {
Q_OBJECT
public:
explicit MyButton(QWidget* parent);
~MyButton() noexcept override;
private:
std::unique_ptr<MyButtonPrivate> const d_ptr;
Q_DECLARE_PRIVATE(MyButton);
Q_PRIVATE_SLOT(d_func(), void onClicked(bool));
};
this is the .h file, compile error: undefined MyButtonPrivate.
truely, the moc_MyButton.cpp(auto generated by compiler) doesnot include the MyButtonPrivate.
then what's wrong, and how to solve?
I'm not sure why it's an error, but according to https://forum.qt.io/topic/61295/solved-what-is-the-usage-of-q_private_slot/3, with Qt > 5 and C++11 it is a useless macro.
the moc file generated:
#include "../../MyButton.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
...
case 0: _t->d_func()->onClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
...
notice: _t->d_func()->onClicked invoke the private class's func(but no include)
so absolutely result in compile error. the question is moc file doesnt include MyButton_p.h, and manually add the include:
#include "../../MyButton.h"
#include "../../MyButton_p.h"
...
then its ok(but the moc file shouldnt modify manually)
I wrote a little program with a my own class within the main.cpp. Here the code:
#include <QApplication>
#include <QPushButton>
#include <QLabel>
class MyWidget : public QWidget {
//Q_OBJECT
public:
MyWidget(QWidget* parent = 0);
QLabel* label;
QString string;
signals:
public slots:
void setTextLabel();
};
void MyWidget::setTextLabel() {
label->setText("Test");
}
MyWidget::MyWidget(QWidget* parent)
: QWidget(parent) {
}
int main(int argc, char** argv) {
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
it seems work but not "completely". My slot doens't work. I suppose i have to put Q_OBJECT. BUT, doing so, I got a list of errors, like this:
undefined reference to `vtable for MyWidget'
........................................
collect2: error: ld returned 1 exit status
make: *** [mywidget] Error 1
I can I manage that? Where the problem?
Signals and slots in Qt are managed through the moc: meta object compiler. Basically, the moc generates additional C++ code for each class containing the Q_OBJECT macro in order to implement effectively the signals and slots mechanisms. The additional code is then linked to the original class declaration.
The problem here is that your class is declared in main.cpp: this conflicts with how the moc is working with your code. You should declare your class in a separate header.
More about the moc
Edit: as hyde pointed, an alternative is to include in your cpp the file generated by the moc: Why is important to include “.moc” file at end of a Qt Source code file?
just append the line #include"main.moc" to your cpp source file should be enough.
More information:
Why is important to include ".moc" file at end of a Qt Source code file?
I'm compiling very simple code and as output I receive error:
`../untitled6/main.cpp:17:1: error: unable to find string literal operator 'operator"" __FILE__'
connect(&d_t, SIGNAL(timeout()), this, SLOT(doPlay()));`
The code is following:
#include <QObject>
#include <QTimer>
class Test : public QObject
{
Q_OBJECT
public:
explicit Test(QObject *parent = 0) : QObject(parent) {}
void Play()
{
connect(&d_t, SIGNAL(timeout()), this, SLOT(doPlay()));
}
public slots:
void doPlay() {}
private:
QTimer d_t;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Test test;
test.Play();
return a.exec();
}
It is happened only if I include c++11 support in my project. Without this support the compilation is Okey. I have read about user-defined literals and whitespace for gcc ver. 4.7 when c++11 support is included. But my code doesn't include any FILE code.... I found that problem is related to SIGNAL and SLOT constructions. But I have no idea what is wrong here...
P.S. For compilation I use sh4-linux-g++ (GCC) 4.8.
I have found that this issue don't observed for release build configuration. It seems it is issue for debug build configuration...
This has been fixed in Qt 4.8.1:
https://bugreports.qt.io/browse/QTBUG-22847
You should upgrade.
I am familiar with Qt4 but we are trying to transition to Qt5 and it's being very difficult. I'm trying to create a very simple application, and I had it working using the Qt PRO file, but we need to base it on cmake to keep the build server happy.
The error I get is "invalid use of incomplete type ‘struct Ui::MainWindow’" in the line in mainwindow.cpp where it constructs "ui(new Ui::MainWindow)".
Here are my files (simplified to shorten this post):
mainwindow.h
#include <QtWidgets/QMainWindow>
namespace Ui { class MainWindow; }
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
mainwindow.cpp
#include "mainwindow.h"
#include "moc_mainwindow.cpp"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ }
MainWindow::~MainWindow()
{ delete ui; }
cmakelists.txt
CMAKE_MINIMUM_REQUIRED( VERSION 2.8.9 FATAL_ERROR )
PROJECT(Test)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
file (GLOB Sources src/*.cpp )
add_executable(Test ${Sources} src/mainwindow.ui )
qt5_use_modules(Test Widgets)
I'm sure I'm missing something obvious, but I've been looking all day and can't figure this one out ...
Looking at the generated moc_mainwindow.cpp (again, some lines truncated to keep this post short):
#include "../src/mainwindow.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
QT_BEGIN_MOC_NAMESPACE
void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_END_MOC_NAMESPACE
I am guessing that MainWindow::qt_static_metacall() is declared in my mainwindow.h in the Q_OBJECT macro. which means I have no idea where this mystical Ui::MainWindow is coming from. Or not.
UPDATE
The problem seems to be that in my mainwindow.cpp, I should be #including "ui_mainwindow.h" instead of "moc_mainwindow.cpp", but there is no "ui_mainwindow.h" being generated, only moc_mainwindow.cpp.
Turns out my understanding of Qt was completely WRONG. moc doesn't generate those ui files, it's doing other magic to make signals & slots work. The solution is to add this link to CMakeLists.txt:
qt5_wrap_ui(uifiles src/mainwindow.ui)
I'm composing a class which derives from QObject, and I want to export this class into a DLL file so other applications can use it. But I got some mysterious problem here:
The code is shown below:
mydll.h:
#ifndef MYDLL_H
#define MYDLL_H
#include "mydll_global.h"
#include <QObject>
#include <QDebug>
class MYDLLSHARED_EXPORT MyDll : public QObject
{
Q_OBJECT
public:
explicit MyDll(QObject * parent = 0);
void test() const;
};
#endif // MYDLL_H
mydll_global.h:
#ifndef MYDLL_GLOBAL_H
#define MYDLL_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(MYDLL_LIBRARY)
# define MYDLLSHARED_EXPORT Q_DECL_EXPORT
#else
# define MYDLLSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // MYDLL_GLOBAL_H
mydll.cpp:
#include "mydll.h"
MyDll::MyDll(QObject * parent) :
QObject(parent)
{
}
void MyDll::test() const {
qDebug() << "Hello from dll!";
}
and the dll is used in another application. The dll is compiled successfully. I've add LIBS += "myDll.dll" in the .pro file of the application using this dll, and I've copied myDll.dll to the working directory of the application.
The compiler reports:
C4273: "MyDll::qt_static_metacall" : inconsistent dll linkage.
C2491: "MyDll::staticMetaObject": definition of dllimport static data member not allowed
What's the problem here?
Your code for mydll_global.h checks whether MYDLL_LIBRARY is defined, but none of the code you have posted defines MYDLL_LIBRARY. Is this declared in a file that you have not shared on the question? If not, you need to add a #define MYDLL_LIBRARY in your build project, or your PCH.