Why won't this compile (link) with the Q_OBJECT macro in place?
I made a prot开发者_StackOverflow中文版otype of a project with PyQt and made it work there, now I'm trying to convert it to C++ and am having some problems.
If I don't put the Q_OBJECT macro in, it compiles and works, but if I comment it out, I get the following errors:
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
Here's the header:
#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
Secondary question is will Bad Things happen if I just omit the Q_OBJECT macro here?
And yes, I'm aware of that it's stupid to call a QGraphicsScene a "view".
This kind of errors usually happen when you add the Q_OBJECT
macro and forget to rerun moc
. If you use qmake
, just run make qmake
after you added the macro.
As for your second question: you won't be able to use signals/slots (among other things) without the Q_OBJECT
macro. See the docs for more information about this.
Recently I tried to compile QDeviceWatcher
on Linux and I get the same error WRT QDeviceWatcherPrivate
class, which declaration can be found in qdevicewatcher_p.h
and definition in qdevicewatcher_linux.cpp
(on Linux).
I use cmake as build system and my CMakeLists.txt
looks like:
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
)
As you can see in add_library
I only provide *.cpp
files. I suspect, that cmake runs Meta object compiler and looks through all the sources, maybe except #include
dependencies, which filenames (w/o extension) not match *.cpp
's filenames (just assumption), for the QObject/QWidget/...
bases and Q_OBJECT
macro. And I think cmake
missed qdevicewatcher_p.h
to look through and run MOC against it.
After I added the "qdevicewatcher_p.h" to the list of sources the error is ceased to exist.
精彩评论