This question is similar to one that has been asked before, but I am having an issue with Qt recognizing my class and functions despite them being defined. I am doing this in linux where the Qt version is only 5.5 while the windows version is at 5.11. When running the same program in windows, I get no errors.
I am getting "undefined reference to QCanBus::instance()" errors
This is happening for every QCanBus function. In my code snippet from connectdialogue.cpp, only the first occurrence is featured and can be found at the second to last code line and gives the errors:
"undefined reference to QCanBus::instance()"
"undefined reference to QCanBus::plugins()"
These errors are given despite being defined in the qcanbus.h headder file.
I have tried adding the lines static QCanBus *instance() or alternatively QCanBus *instance() under the #include lines in my connectdialogue.cpp, but I am then presented with the warning:
"QCanBus::instance() is defined, but unused" when it is clearly used on the second to last line of the featured code snippet.
How do I fix these errors?
connectdialogue.cpp
#include "connectdialog.h"
#include "ui_connectdialog.h"
#include "qcanbus.h"
ConnectDialog::ConnectDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::ConnectDialog)
{
m_ui->setupUi(this);
m_ui->errorFilterEdit->setValidator(new QIntValidator(0, 0x1FFFFFFFU, this));
m_ui->loopbackBox->addItem(tr("unspecified"), QVariant());
m_ui->loopbackBox->addItem(tr("false"), QVariant(false));
m_ui->loopbackBox->addItem(tr("true"), QVariant(true));
m_ui->receiveOwnBox->addItem(tr("unspecified"), QVariant());
m_ui->receiveOwnBox->addItem(tr("false"), QVariant(false));
m_ui->receiveOwnBox->addItem(tr("true"), QVariant(true));
m_ui->canFdBox->addItem(tr("false"), QVariant(false));
m_ui->canFdBox->addItem(tr("true"), QVariant(true));
m_ui->dataBitrateBox->setFlexibleDateRateEnabled(true);
connect(m_ui->okButton, &QPushButton::clicked, this, &ConnectDialog::ok);
connect(m_ui->cancelButton, &QPushButton::clicked, this, &ConnectDialog::cancel);
connect(m_ui->useConfigurationBox, &QCheckBox::clicked,
m_ui->configurationBox, &QGroupBox::setEnabled);
connect(m_ui->backendListBox, &QComboBox::currentTextChanged,
this, &ConnectDialog::backendChanged);
connect(m_ui->interfaceListBox, &QComboBox::currentTextChanged,
this, &ConnectDialog::interfaceChanged);
m_ui->rawFilterEdit->hide();
m_ui->rawFilterLabel->hide();
m_ui->backendListBox->addItems(QCanBus::instance()->plugins());
updateSettings();
}
qcanbus.h
#ifndef QCANBUS_H
#define QCANBUS_H
#include <QtCore/qobject.h>
#include "qserialbusglobal.h"
#include "qcanbusdevice.h"
#include "qcanbusdeviceinfo.h"
QT_BEGIN_NAMESPACE
class Q_SERIALBUS_EXPORT QCanBus : public QObject
{
Q_OBJECT
public:
static QCanBus *instance();
QStringList plugins() const;
QList<QCanBusDeviceInfo> availableDevices(const QString &plugin, QString *errorMessage = nullptr) const;
QCanBusDevice *createDevice(const QString &plugin,
const QString &interfaceName,
QString *errorMessage = nullptr) const;
private:
QCanBus(QObject *parent = nullptr);
Q_DISABLE_COPY(QCanBus)
};
QT_END_NAMESPACE
#endif // QSERIALBUS_H
QCanBus was missing QCanBus.cpp and was not declared.
Related
I am using Qt 5.7.1 (5.8) and when I try to compile my project, I get an error:
Error: C2664: "void Ui_OverviewHistogram::setupUi(QFrame *)" :
Converting from argument 1 of "OverviewHistogram *const " to "QFrame
*" not possible
(translated from german)
and I have no idea why... The strange thing is, that a lot of seamingly similar classes compile without any issue, just this one will not work. I tried to change the ui to a pointer, but it did not work.
The ui_overviewhistogram component of this class is a simple QFrame object designed completely in the Qt designer without any outside manual code 'hacking'.
I am relatively new to C++ and Qt and I can't figure out a solution (not even why this is a problem), can anyone help me with it?
My code:
overviewhistogram.h
#ifndef OVERVIEWHISTOGRAM_H
#define OVERVIEWHISTOGRAM_H
#include <QFrame>
#include <QColormap>
#include "AnalysisSession.h"
#include "ui_overviewhistogram.h"
namespace Ui {
class OverviewHistogram;
}
class OverviewHistogram : public QFrame
{
Q_OBJECT
public:
OverviewHistogram(Examination *examination, double max = 400, int w = 175, QWidget *parent = 0);
...
}
#endif // OVERVIEWHISTOGRAM_H
overviewhistogram.cpp
OverviewHistogram::OverviewHistogram(Examination *examination, double max, int w, QWidget *parent) :
QFrame(parent)
{
ui.setupUi(this);
...
}
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 am trying to add property title into the main window of my application. But when I try to compile it, the compiler gives me this error:
mainwindow.cpp:19: undefined reference to `MainWindow::titleChanged(QString const&)'
I tried it on mingw and msvc2013 both fails on the same line with this error. The header/source files:
mainwindow.h:
#ifndef MAINWINDOW
#define MAINWINDOW
#include <QObject>
#include <QString>
class MainWindow : public QObject {
QOBJECT_H
Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged)
public:
MainWindow();
QString getTitle();
public slots:
void setTitle(const QString& title);
signals:
void titleChanged(const QString& title);
private:
QString title_;
};
#endif // MAINWINDOW
mainwindow.cpp:
#include "mainwindow.h"
#include <QString>
MainWindow::MainWindow()
{
}
QString MainWindow::getTitle()
{
return title_;
}
void MainWindow::setTitle(const QString& title)
{
if (title_ != title) {
title_ = title;
emit titleChanged(title);
}
}
If I add the method below to the end of mainwindow.cpp file, then the application compiles and runs, but the signal isn't emitted:
void MainWindow::titleChanged(const QString&)
{
}
I tried to cleaning out the project's build folders, it doesn't help :(. I am using QT 5.4 and working on QT Creator.
This question was already answered in comments by someone else. I just wanted to highlight the answer. The error in my case was in the header file
mainwindow.h:
class MainWindow : public QObject {
QOBJECT_H // This should be Q_OBJECT
...
I confused the QOBJECT_H macro used in QObject.h header file as an include guard with the Q_OBJECT macro used by QT's moc tool. Since the intellisense will offer you both options, they are easy to confuse.
I also got pointed to a good reading about common problems with signals/slots worth for reading: My signal / slot connection does not work
This question already has answers here:
Undefined reference to vtable. Trying to compile a Qt project
(21 answers)
Closed 9 years ago.
I'm trying to program a Qt GUI in C++. Here is the code:
sample.h:
#ifndef SAMPLE_H
#define SAMPLE_H
#include <QtGui/QApplication>
#include <QtGui/QPushButton>
#include <QtGui/QWidget>
#include <QtGui/QGridLayout>
#include <QtGui/QLineEdit>
#include <qobject.h>
class Sample : public QObject
{
Q_OBJECT
public:
Sample();
public slots:
void buttonPressed();
private:
QWidget *widget;
QGridLayout *layout;
QLineEdit *le;
QPushButton *button;
};
#endif // SAMPLE_H
sample.cpp:
#include "sample.h"
Sample::Sample()
{
widget = new QWidget();
widget->setWindowTitle("Sample");
layout = new QGridLayout();
le = new QLineEdit();
button = new QPushButton();
button->setText("Button");
connect(button, SIGNAL(clicked()), this, SLOT(buttonPressed()));
layout->addWidget(le, 0, 0);
layout->addWidget(button, 1 , 0);
widget->resize(300, 300);
widget->setLayout(layout);
widget->show();
}
void Sample::buttonPressed(){
le->setText("pressed");
}
I obtain this error when building:
error: undefined reference to `vtable for Sample'
I'm using QtCreator from official Qt webpage.
Does anybody know what to do to make it work? Thank you very much for your responses :)
This kind of error usually occurs if you add the Q_OBJECT macro after having written and compiling your class. Rerunning qmake will usually fix it.
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.