Почему эта компиляция (ссылка) не выполняется с макросом Q_OBJECT? - PullRequest
3 голосов
/ 31 августа 2010

Я сделал прототип проекта с 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 ]

7 голосов
/ 31 августа 2010

Этот тип ошибок обычно возникает, когда вы добавляете макрос Q_OBJECT и забыли перезапустить moc.Если вы используете qmake, просто запустите make qmake после добавления макроса.

Что касается вашего второго вопроса: вы не сможете использовать сигналы / слоты (среди прочего) без Q_OBJECT макрос.См. документы для получения дополнительной информации об этом.

1 голос
/ 22 июня 2017

Недавно я попытался скомпилировать QDeviceWatcher в Linux и получаю ту же ошибку класса WRT QDeviceWatcherPrivate, объявление которого можно найти в qdevicewatcher_p.h, а определение в qdevicewatcher_linux.cppLinux ).

Я использую 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/... баз и макроса Q_OBJECT. И я думаю, cmake пропустил qdevicewatcher_p.h, чтобы просмотреть и запустить MOC против него.

После того как я добавил «qdevicewatcher_p.h» в список источников, ошибка перестала существовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...