为什么不与Q_OBJECT宏进行编译(链接)?

时间:2010-08-31 08:22:56

标签: c++ qt linker qobject

我用PyQt制作了一个项目原型并使其在那里工作,现在我正在尝试将其转换为C ++并遇到一些问题。

如果我没有放入Q_OBJECT宏,它会编译并运行,但如果我发表评论,我会收到以下错误:

Undefined symbols:
  "vtable for MapView", referenced from:
      MapView::~MapView()in mapview.o
      MapView::~MapView()in mapview.o
      MapView::MapView(QObject*)in mapview.o
      MapView::MapView()in mapview.o
  "MapView::staticMetaObject", referenced from:
      MapView::MapView(QObject*)in mapview.o
      MapView::MapView()in mapview.o

这是标题:

#ifndef MAPVIEW_H
#define MAPVIEW_H

#include <QtGui>
#include <QObject>

class MapView : public QGraphicsScene
{
    //Q_OBJECT

public:
    MapView();
    explicit MapView(QObject *parent = 0);
    QGraphicsPixmapItem *mappixmap;
    ~MapView();

private:
    bool dragging;
    float offsetX, offsetY, downoffsetX, downoffsetY;

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

};

#endif // MAPVIEW_H

如果我在这里省略Q_OBJECT宏,那么第二个问题是坏事会发生吗?

是的,我知道将QGraphicsScene称为“视图”是愚蠢的。

2 个答案:

答案 0 :(得分:7)

当您添加Q_OBJECT宏并忘记重新运行moc时,通常会发生此类错误。如果您使用qmake,请在添加宏后运行make qmake

关于你的第二个问题:如果没有Q_OBJECT宏,你将无法使用信号/插槽(以及其他内容)。有关详细信息,请参阅docs

答案 1 :(得分:1)

最近我尝试在 Linux 上编译QDeviceWatcher,我得到了同样的错误WRT QDeviceWatcherPrivate类,该声明可以在qdevicewatcher_p.h中找到并在qdevicewatcher_linux.cpp(在 Linux 上)。

我使用 cmake 作为构建系统,我的CMakeLists.txt看起来像:

cmake_minimum_required(VERSION 3.8)

project("QDeviceWatcher" LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOMOC ON)

find_package(Qt5 REQUIRED COMPONENTS Core Network)

set(SOURCES)
list(APPEND SOURCES "qdevicewatcher.cpp")
if(WINCE)
    list(APPEND SOURCES "qdevicewatcher_wince.cpp")
elseif(WIN32)
    list(APPEND SOURCES "qdevicewatcher_win32.cpp")
elseif(APPLE)
    list(APPEND SOURCES "qdevicewatcher_mac.cpp")
elseif(UNIX)
    list(APPEND SOURCES "qdevicewatcher_linux.cpp")
else()
    message(FATAL_ERROR "no supported platform detected")
endif()

add_library(${PROJECT_NAME} STATIC ${SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ".")

target_link_libraries(${PROJECT_NAME} PUBLIC Qt5::Core Qt5::Network)

set_target_properties(${PROJECT_NAME} PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED YES
    CXX_EXTENSIONS YES
    )

正如您在add_library中看到的,我只提供*.cpp个文件。我怀疑, cmake 运行元对象编译器并查看所有源,可能除了#include依赖项,哪些文件名(没有扩展名)不匹配{对于*.cpp基础和QObject/QWidget/...宏,{1}}的文件名(只是假设)。我认为Q_OBJECT错过cmake来查看并运行 MOC

将“qdevicewatcher_p.h”添加到源列表后,错误不再存在。