【问题标题】:Can I automoc a header only object that inherits QObject?我可以 automoc 继承 QObject 的仅标头对象吗?
【发布时间】:2018-05-21 16:47:17
【问题描述】:

我对 Qt 比较陌生,我正在将它整合到我们的项目中。我做了一个非常小的对象,它继承了我只与计时器一起使用的 QObject。我为它创建了一个仅头文件,但很快意识到编译器不喜欢它。所以我为它创建了一个免费的 .cpp 文件来消除错误,它似乎可以工作。

我的问题是真的,我可以创建一个只继承 QObject 的标头对象并允许它自动进行吗?还是我每次都需要创建一个免费的 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"

【问题讨论】:

  • 如果您将Header.h 添加到add_executable(...)(或target_sources,如果您可以将您的cmake 版本升级到3.1)会发生什么?

标签: c++ qt cmake header-only


【解决方案1】:

有两种解决方案:

  1. 在项目中明确包含头文件,就像在 .pro 文件中一样:

    add_executable(test "Main.cpp" "Header.h")
    
  2. .cpp 文件的任何一个(并且只有一个)中添加#include "moc_Header.cpp",例如在Main.cpp:

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

    如果您在执行此操作时收到 CMP0071 政策警告 - 这是虚假的。您需要删除构建文件夹并重新运行 cmake 以重新配置构建。

【讨论】:

    【解决方案2】:

    在源列表中包含头文件:

    add_executable(test Main.cpp Header.h)
    

    这会让 CMake 知道你有一个带有 QObject 声明的头文件。因此它会自动 (CMAKE_AUTOMOC ON) 计算出它需要运行 moc 并将其包含到构建中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 2023-03-28
      • 2017-11-11
      • 2011-05-23
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多