我对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"
答案 0 :(得分:1)
有两种解决方案:
在项目中显式包含头文件,就像在.pro
文件中一样:
add_executable(test "Main.cpp" "Header.h")
在#include "moc_Header.cpp"
个文件的任何一个(且只有一个)中添加.cpp
,例如在Main.cpp
:
// Main.cpp
...
#include "moc_Header.cpp"
如果您在执行此操作时收到CMP0071
政策警告 - 这是虚假的。您需要删除构建文件夹并重新运行cmake以重新配置构建。
答案 1 :(得分:0)
另一种解决方案是将头文件包含在构建中:
grandparent = GrandParent('dad')
grandparent.parent = Parent('bob')
grandparent.parent.children.append(Child('alice', 1))
grandparent.parent.children.append(Child('jo', 2))
grandparent.parent.children.append(Child('blo', 3))
foo = Child('foo', 4)
grandparent.parent.children.append(foo)
session.add(grandparent)
print(foo.grandparent.parent.id)
这会让CMake知道你有一个带有add_executable(test Main.cpp Header.h)
声明的头文件。因此它会自动计算(QObject
)它需要运行CMAKE_AUTOMOC ON
并将其包含在构建中。