在Qt-program中我实现了Pimpl方法,有3个文件
saction.cpp
saction.h
saction_p.h - with a private class sactionPrivate
代码基于kdelibs的代码。我正在使用CMAKE作为构建系统。所以我在编译时遇到错误
build / moc_saction.cpp:73:22:错误:无效使用不完整类型'class SActionPrivate' actions / saction.h:492:18:错误:'class SActionPrivate'的前向声明
问题出在文件 moc_saction.cpp 中,它不包含文件 saction_p.h ,只有 saction.h < / p>
所以我需要在生成的moc文件中手动添加该行:
#include "../actions/saction_p.h"
我该怎么办,为了不手动纠正moc文件???
CMakeLists.txt
project(scalc)
cmake_minimum_required(VERSION 2.6)
find_package(Qt4 REQUIRED)
include_directories(
${QT_INCLUDES}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/actions
)
set(scalc_SRCS
actions/saction.cpp
main.cpp )
set(CMAKE_AUTOMOC ON)
add_executable(scalc ${scalc_SRCS} )
target_link_libraries(scalc ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
install(TARGETS scalc RUNTIME DESTINATION bin)
操作/ saction.h
#ifndef SACTION_H
#define SACTION_H
#include <QtGui/QWidgetAction>
class SAction : public QWidgetAction
{
Q_OBJECT
public:
explicit SAction(QObject *parent);
virtual ~SAction();
private:
friend class SActionPrivate;
class SActionPrivate* const d;
Q_PRIVATE_SLOT(d, void slotTriggered())
};
#endif
操作/ saction_p.h
#ifndef SACTION_P_H
#define SACTION_P_H
class SAction;
class SActionPrivate
{
public:
SActionPrivate():q(0)
{
}
void slotTriggered();
void init(SAction *q_ptr);
SAction *q;
};
#endif
操作/ saction.cpp
#include "saction.h"
#include "saction_p.h"
#include <QtGui/QApplication>
#include <QtGui/QHBoxLayout>
#include <QtGui/QShortcutEvent>
#include <QtGui/QToolBar>
void SActionPrivate::init(SAction *q_ptr)
{
q = q_ptr;
QObject::connect(q, SIGNAL(triggered(bool)), q, SLOT(slotTriggered()));
q->setProperty("isShortcutConfigurable", true);
}
void SActionPrivate::slotTriggered()
{}
SAction::SAction(QObject *parent)
: QWidgetAction(parent), d(new SActionPrivate)
{
d->init(this);
}
SAction::~SAction()
{
delete d;
}
的main.cpp
#include "saction.h"
int main(int argc, char** argv)
{
SAction gg(new QWidget());
}
由cmake moc_saction.cpp生成
#include "../actions/saction.h"
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'kaction.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 63
#error "This file was generated using the moc from 4.8.6. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_SAction[] = {
// content:
6, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: signature, parameters, type, tag, flags
9, 8, 8, 8, 0x08,
0 // eod
};
static const char qt_meta_stringdata_SAction[] = {
"SAction\0\0slotTriggered()\0"
};
void SAction::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
SAction *_t = static_cast<SAction *>(_o);
switch (_id) {
case 0: _t->d->slotTriggered(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData SAction::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject SAction::staticMetaObject = {
{ &QWidgetAction::staticMetaObject, qt_meta_stringdata_SAction,
qt_meta_data_SAction, &staticMetaObjectExtraData }
};
#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &SAction::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION
const QMetaObject *SAction::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}
void *SAction::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_SAction))
return static_cast<void*>(const_cast< SAction*>(this));
return QWidgetAction::qt_metacast(_clname);
}
int SAction::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidgetAction::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
}
return _id;
}
QT_END_MOC_NAMESPACE
答案 0 :(得分:2)
是的,你在这里有两个问题:
缺少生成moc的cmake二进制目录的includepath
${CMAKE_CURRENT_BINARY_DIR}
您需要在相应的源文件末尾包含moc文件
#include "moc_saction.cpp"