Reputation: 103
I'm just starting learning Qt and currently I'm reading the book Learn Qt 5 by Nicolas Sheriff. Where I am, in chapter 2, I'm following all the instructions and I'M understanding what I am doing but i getting stuck on one thing: when i compile the following program along with others, I'm getting this list of errors:image shwowing the error messages
Here's the project structure
and the files I find worth showing are:
cm.pro file
QT -= gui
TARGET = cm-lib
TEMPLATE = lib
CONFIG += c++17
DEFINES += CMLIB_LIBRARY
INCLUDEPATH += source
SOURCES += source/models/client.cpp \
source/controllers/master-controller.cpp \
HEADERS += source/cm-lib_global.h \
source/controllers/master-controller.h \
source/models/client.h \
cm-lib.pro
QT -= gui
TARGET = cm-lib
TEMPLATE = lib
CONFIG += c++17
DEFINES += CMLIB_LIBRARY
INCLUDEPATH += source
SOURCES += source/models/client.cpp \
source/controllers/master-controller.cpp \
HEADERS += source/cm-lib_global.h \
source/controllers/master-controller.h \
source/models/client.h \
cm-ui.pro
QT += qml quick
TEMPLATE = app
CONFIG += c++17
INCLUDEPATH += source \
../cm-lib/source
SOURCES += source/main.cpp
RESOURCES += views.qrc
LIBS += -L$$PWD/../../build-cm-kit1-Debug/cm-lib/ -lcm-lib
MasterController.h
#ifndef MASTERCONTROLLER_H
#define MASTERCONTROLLER_H
#include <QObject>
#include <QString>
#include <cm-lib_global.h>
namespace cm::controllers {
class CMLIBSHARED_EXPORT MasterController : public QObject
{
Q_OBJECT
QString welcomeMessage = "This is MasterController to Major Tom";
Q_PROPERTY( QString ui_welcomeMessage MEMBER welcomeMessage CONSTANT )
public:
explicit MasterController(QObject* parent = nullptr);
};
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <controllers/master-controller.h>
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterType<cm::controllers::MasterController>("CM", 1, 0, "MasterController");
cm::controllers::MasterController masterController{};
QQmlApplicationEngine engine{};
engine.rootContext()->setContextProperty("masterController", &masterController);
engine.load(QUrl(QStringLiteral("qrc:/views/MasterView.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
It' long like that because I used the MVC design pattern here like in the book.
I think the problem is caused by the inclusion of the Q_OBJECT macro in MasterController.h
because when I remove it, the project compile well without any issue.
After googling about the issue, on almost all the places I visited, the error was caused by the fact that the classes including Q_OBJECT macro would be declared in their own header file or qmake
was not rerunned on these files including Q_OBJECT but It's not true in my case.
System tools used:
Upvotes: 6
Views: 8376
Reputation: 1
I was getting same error for QWebSocketServer class.
was fixed by adding following line to .pro file
QT += websockets
Upvotes: 0
Reputation: 2316
Your code itself is OK and compiles, but you're missing a library in linking.
That's because you #include <QGuiApplication>
, but you removed gui in thos line in your .pro:
QT -= gui
Solution:
QT += gui <and any other libraries you've used, e.g. bluetooth>
Upvotes: 0
Reputation: 1069
Simply change MEMBER to READ in the Q_PROPERTY solved this problem for me tho.
Took me hours :) You're welcome.
MasterController.h
#ifndef MASTERCONTROLLER_H
#define MASTERCONTROLLER_H
#include <QObject>
#include <QString>
#include <cm-lib_global.h>
namespace cm::controllers {
class CMLIBSHARED_EXPORT MasterController : public QObject
{
Q_OBJECT
QString welcomeMessage = "This is MasterController to Major Tom";
Q_PROPERTY( QString ui_welcomeMessage READ welcomeMessage CONSTANT ) //<-----MEMBER to READ
public:
explicit MasterController(QObject* parent = nullptr);
};
}
Btw.: In the error message (of the screenshot you included in the question) you can right click and expand the message Show Output
in the qt creator. Normally the error has a zickzackely underlining in there.
Upvotes: 0
Reputation: 126
The undefined reference is most likely caused by a missing moc file. When subclassing a qt object and using the Q_OBJECT macro the Qt Meta-Object Compiler creates a moc file (moc_master-controller.cpp) containing qobject related definitions including the missing staticMetaObject
. This source file has to be compiled with the class definition. This is done automatically when using qmake.
Based on the code you provided your setup should be working. A few things to try:
I tried reproducing the issue based on the code you provided but it compiled fine for me. In case you want to cross-reference with your code I've included mine below.
cm-lib.pro
QT -= gui
TARGET = cm-lib
TEMPLATE = lib
CONFIG += c++17
DEFINES += CMLIB_LIBRARY
INCLUDEPATH += source
SOURCES += master-controller.cpp
HEADERS += cm-lib_global.h \
master-controller.h
cm-lib_global.h
#pragma once
#include <QtCore/QtGlobal>
#if defined(CMLIB_LIBRARY)
# define CMLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define CMLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
master-controller.h
#pragma once
#include <QObject>
#include <QString>
#include <cm-lib_global.h>
namespace cm::controllers {
class CMLIBSHARED_EXPORT MasterController : public QObject
{
Q_OBJECT
QString welcomeMessage = "This is MasterController to Major Tom";
Q_PROPERTY( QString ui_welcomeMessage MEMBER welcomeMessage CONSTANT )
public:
explicit MasterController(QObject* parent = nullptr);
};
}
master-controller.cpp
#include "master-controller.h"
cm::controllers::MasterController::MasterController(QObject* parent):
QObject(parent)
{
}
cm-ui.pro
QT += qml quick
TEMPLATE = app
CONFIG += c++17
INCLUDEPATH += ../cm-lib
SOURCES += main.cpp
LIBS += -L"../build-cm-lib-Desktop_Qt_5_12_1_MinGW_64_bit-Debug\debug" -lcm-lib
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <master-controller.h>
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterType<cm::controllers::MasterController>("CM", 1, 0, "MasterController");
cm::controllers::MasterController masterController{};
QQmlApplicationEngine engine{};
engine.rootContext()->setContextProperty("masterController", &masterController);
engine.load(QUrl(QStringLiteral("qrc:/views/MasterView.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
Upvotes: 7