Могу ли я автомочить заголовок только объект, который наследует QObject? - PullRequest
0 голосов
/ 21 мая 2018

Я относительно новичок в Qt и включаю его в наши проекты.Я сделал очень маленький объект, который наследует QObject, который я просто использую с таймером.Я создал для него только заголовочный файл, но понял, что компилятору это быстро не понравилось.Поэтому я создал бесплатный файл .cpp, чтобы избавиться от ошибок, и он, похоже, работает.

Мой вопрос действительно заключается в том, могу ли я создать объект только для заголовков, который наследует QObject, и позволить ему получить automoc 'ред?Или мне нужно будет каждый раз создавать бесплатный файл cpp?

Я сгенерировал меньшее количество кода для репликации, который показывает, что я имею в виду.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.11)

# Standardly
set(CMAKE_CXX_STANDARD 11)

# Findn includes in corresponding directories?
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed
set(CMAKE_AUTOMOC ON)

find_package(Qt5Widgets)

add_executable(test Main.cpp)

target_link_libraries(test Qt5::Widgets)

Main.cpp

#include <QApplication>

#include "Header.h"

int main( int argc, char *argv[] )
{
    QApplication app( argc, argv );

    HeaderOnly();

    return( app.exec() );
}

Header.h

#ifndef HEADER_H
#define HEADER_H

#include <QObject>
#include <QTimer>
#include <QDebug>

class HeaderOnly : public QObject
{
    Q_OBJECT

    public:
        HeaderOnly() :
            timer_( new QTimer( this ) )
        {
            QObject::connect( timer_, SIGNAL( timeout() ), this, SLOT( timeout() ) );

            timer_->start( 1000 );
        }

    private slots:
        void timeout()
        {
            qDebug() << "Why hello!";
        }

    private:
        QTimer *timer_;
};

#endif

Выход

$ make
[ 25%] Automatic MOC for target test
Generating MOC predefs moc_predefs.h
[ 25%] Built target test_autogen
Scanning dependencies of target test
[ 50%] Building CXX object CMakeFiles/test.dir/Main.cpp.o
[ 75%] Linking CXX executable test
CMakeFiles/test.dir/Main.cpp.o: In function `HeaderOnly::HeaderOnly()':
Main.cpp:(.text._ZN10HeaderOnlyC2Ev[_ZN10HeaderOnlyC5Ev]+0x32): undefined reference to `vtable for HeaderOnly'
CMakeFiles/test.dir/Main.cpp.o: In function `HeaderOnly::~HeaderOnly()':
Main.cpp:(.text._ZN10HeaderOnlyD2Ev[_ZN10HeaderOnlyD5Ev]+0xf): undefined reference to `vtable for HeaderOnly'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:124: test] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

Конечно, добавление этого Header.cpp к источнику устранит ошибку:

#include "Header.h"

#include "moc_Header.cpp"

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Включить файл заголовка в список источников:

add_executable(test Main.cpp Header.h)

Это позволит CMake знать, что у вас есть файл заголовка с объявлением QObject.Таким образом, он автоматически выясняет (CMAKE_AUTOMOC ON), что ему нужно запустить moc и включить его в сборку.

0 голосов
/ 21 мая 2018

Существует два решения:

  1. Включите файл заголовка в проект явным образом, как в файле .pro:

    add_executable(test "Main.cpp" "Header.h")
    
  2. Добавьте #include "moc_Header.cpp" в любой один (и только один) из .cpp файлов, например, в Main.cpp:

    // Main.cpp
    ...
    #include "moc_Header.cpp"
    

    Если вы получитеCMP0071 политическое предупреждение, когда вы это делаете - это ложно.Вам нужно удалить папку сборки и перезапустить cmake для перенастройки сборки.

...