QT undefined reference compilation error on a signal - c++

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

Related

Qt creator Undefined reference to "class::function" in linux

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.

Building Qt project with CMake and inheriting from QMainWindow leads to unreferenced vtable error

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")

Subclass of QEditLine with a new SIGNAL

I am trying to subclass QEditLine so that I can define a new SIGNAL that sends an object identifier. At the moment, I connect a parent signal to a slot in the new class and from that slot I emits a proper new signal with the additional object identifier.
I cannot understand one thing. The problem is I don't know how to define a new signal function itself. I don't know what I should put there. I mean I know its arguments but I don't know what it shpould do as a function. I am doing this for the first time and it may looks very silly ;p but I really stuck there >.<.
Can anybody please provide some clues. It is probably a very easy problem.
Thanks
// myqeditline.h
#ifndef MYQEDITLINE_H
#define MYQEDITLINE_H
#include <QWidget>
#include <QLineEdit>
#include <QString>
class MyQEditLine : public QLineEdit
{
Q_OBJECT
public:
explicit MyQEditLine(const QString& n, QWidget *parent = 0);
protected:
QString name;
signals:
void textChanged(QString textCHanged, QString sender);
protected slots:
public slots:
void myTextChanged(QString textChanged);
};
#endif // MYQEDITLINE_H
// myqeditline.cpp
#include "myqeditline.h"
MyQEditLine::MyQEditLine(const QString &n, QWidget *parent)
: QLineEdit(parent),name(n) {
connect(this,SIGNAL(textChanged(QString)),this,SLOT(myTextChanged(QString)));
}
void MyQEditLine::myTextChanged(QString textChanged) {
emit textChanged(QString textChanged, QString name);
}
I just realised that the answer to my question is on this Qt Project website, in section regarding "Signals", in 4th paragraph. It says: "Signals are automatically generated by the moc and must not be implemented in the .cpp file. They can never have return types (i.e. use void)."

Reading large Files

I want to read a 50MB file and send it over tcp. The file contains only floats. First I created only a Mainwindow, witch reads one line and sends it to the Server, but the gui got frozen. So I created a class that depends on QThread called QSendThread. Here is the Code for the class QThread:
#ifndef QSENDTHREAD_H
#define QSENDTHREAD_H
#include <QThread>
#include <QLabel>
#include <QFile>
#include <QMessageBox>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>
class QSendThread : public QThread
{
Q_OBJECT
public:
QSendThread(QTcpSocket* qtcpso, QLabel* qlbl, QFile* qfiel, QObject *parent = NULL);
~QSendThread();
protected:
void run(void);
private:
QTcpSocket* qtcpsoDest;
QLabel* qlblRef;
QFile* qfileRef;
signals:
void error(QString qstrError);
};
#endif // QSENDTHREAD_H
#include "qsendthread.h"
QSendThread::QSendThread(QTcpSocket* qtcpso, QLabel* qlbl, QFile* qfile, QObject *parent)
: QThread(parent)
{
qtcpsoDest = qtcpso;
qlblRef = qlbl;
qfileRef = qfile;
}
QSendThread::~QSendThread()
{
}
void QSendThread::run(void)
{
int iLine = 0;
do
{
QByteArray qbarrBlock;
QDataStream qdstrmOut(&qbarrBlock, QIODevice::WriteOnly);
// show witch line is read
qlblRef->setText(tr("Reading Line: %1").arg(++iLine));
qdstrmOut.setVersion(QDataStream::Qt_4_6);
qdstrmOut << (quint16)0;
qdstrmOut << qfileRef->readLine().data();
qdstrmOut.device()->seek(0);
qdstrmOut << (quint16)(qbarrBlock.size() - sizeof(quint16));
qtcpsoDest->write(qbarrBlock);
qtcpsoDest->flush();
qbarrBlock.clear();
} while(!qfileRef->atEnd());
}
But the program crashing in the method qregion::qt_region_strictContains(const QRegion &region, const QRect &rect)
Is the method to read the file like I am doing wrong?
Thanks for Help.
First, you shouldn't really need to subclass QThread. The Qt documentation is misleading on this point. See this accepted answer for a similar question for lots of good info.
Second, you can only correctly access the gui from the main thread so your call qlblRef->setText() would be a problem. Accessing the gui from a thread other than the main one can be done using signals and slots or postEvent(). You can read up on events here.
Finally, this documentation is really required reading for working with threads in Qt. Pay particular attention to the section on threads and QObjects.
Addition:
To follow the advice above, you could certainly wrap your file reading code in a QObject subclass. An alternative (which I have little experience with myself) may be to try putting your code in QtConcurrent::run() and getting the result with a QFuture.

ISO C++ forbids declaration of 'QPushButton' with no type in QT Creator

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.