未定义对MasterController :: StaticMetaObject的引用

时间:2019-02-10 20:59:38

标签: c++ qt

我刚刚开始学习Qt,目前正在阅读Nicolas Sheriff撰写的书 Learn Qt 5 。我在哪里,在第2章中,我正在按照所有说明进行操作,并且我了解自己的工作,但是我只能做一件事:与其他程序一起编译以下程序时,我会收到此错误列表:image shwowing the error messages

这里是project structure

我发现值得展示的文件是:

cm.pro文件

Tools

cm-lib.pro

public class MainActivity extends AppCompatActivity {

List<Item> it;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);   
    }

    public void clicked(View view) {          
        getCompany(s);
        Integer.toString(it.size());  
    }

    public void getCompany(String name) {

        apiCall.setCallback(new ApiCall.NetworkCallback() {
            @Override
            public void onResponse(List<Item> items) {
                 it = items;
                for (int i = 0; i < items.size(); i++) {    
                    Log.d("Name", it.get(i).getTitle());
                }
            }
        });
    }

cm-ui.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 \

MasterController.h

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 \

main.cpp

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

之所以这么长,是因为我像本书一样使用了MVC设计模式。

我认为问题是由#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); }; } 中包含Q_OBJECT宏引起的,因为当我删除它时,项目可以很好地编译而没有任何问题。

在搜索了该问题之后,几乎在我访问过的所有地方,该错误都是由于以下事实引起的:包括Q_OBJECT宏在内的类将在其自己的头文件中声明,或者未在这些文件上重新运行#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(); } 包括Q_OBJECT,但对我而言并非如此。

使用的系统工具:

  • Qt创建者
  • Qt 5.11 -Kubuntu 18.04

3 个答案:

答案 0 :(得分:1)

未定义的引用很可能是由于缺少moc文件引起的。当对qt对象进行子类化并使用Q_OBJECT宏时,Qt元对象编译器会创建一个moc文件(moc_master-controller.cpp),其中包含与qobject相关的定义,包括缺少的staticMetaObject。此源文件必须使用类定义进行编译。使用qmake时会自动完成。

根据您提供的代码,设置应该可以正常工作。可以尝试的几件事:

  • 再次运行qmake。添加或删除Q_OBJECT宏后,必须再次运行qmake。如果在运行qmake之后在 之后添加了Q_OBJECT,则makefile不包含master-controller.h的moc命令。
  • 确保从lib正确导出了类,并且另一个项目找到了lib并正确导入了。
  • 如果在以前的构建过程中出现问题,则值得尝试进行清理和重建。

我尝试根据您提供的代码重现该问题,但对我来说编译很好。如果您想与您的代码进行交叉引用,我将在下面列出。

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

主控制器.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();
}

答案 1 :(得分:0)

只需将Q_PROPERTY中的MEMBER更改为READ就可以解决此问题 对我来说

花些时间:)不客气。

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);
    };
    }

顺便说一句:在错误消息(包含在问题中的屏幕快照中)中,您可以右键单击并在qt创建器中展开消息Show Output。通常,该错误在其中有一个zickzackely下划线。

enter image description here

答案 2 :(得分:0)

您的代码本身没问题并且可以编译,但是您在链接中缺少一个库。

那是因为您var countryBorders = result.data; // inside th function that collects the borders var countryBorders; // remove any previously assigned borders first countryBorders.remove() // proceed countryBorders = L.geoJSON(countryBorders, { style: { fillOpacity: 0.0, color: 'red', weight: 2 } }).addTo(map); ,但您删除了 .pro 中 thos 行中的 gui:

#include <QGuiApplication>

解决方案:

QT       -= gui