Проблема возникает из-за Forward Declaration тут:
namespace Ui {
class Widget;
}
MOC еще не сгенерил .cpp файлы и размер класса еще не известен. Как я понял размер класса нужен QSharedPointer для удаления указателя, но например в таком случае все великолепно:
#include <QtCore/QCoreApplication>
#include <QtCore/QSharedPointer>
class Data;
class Object : public QObject
{
Q_OBJECT
Q_PROPERTY(QSharedPointer<Data> value READ value WRITE setValue)
public:
QSharedPointer<Data> value() const {return m_value;}
void setValue(QSharedPointer<Data> value) {m_value = value;}
private:
QSharedPointer<Data> m_value;
};
struct Data
{
int m_value;
float m_value2;
};
int main(int argc, char **argv)
{
QCoreApplication a(argc, argv);
Object obj;
obj.setValue(QSharedPointer<Data>(new Data));
obj.value()->m_value = 1;
obj.value()->m_value2 = 2;
return 0;
}
#include "moc_main.cpp"
Проблемные исходники:
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget {
Q_OBJECT
Q_PROPERTY(QSharedPointer<Ui::Widget> ui READ ui WRITE setUi)
public:
Widget(QWidget* parent = 0);
QSharedPointer<Ui::Widget> ui() const {return m_ui;}
void setUi(QSharedPointer<Ui::Widget> ui) {m_ui = ui;}
~Widget();
protected:
void changeEvent(QEvent* e);
private:
QSharedPointer<Ui::Widget> m_ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget* parent) :
QWidget(parent)
{
setUi(QSharedPointer<Ui::Widget>(new Ui::Widget));
ui()->setupUi(this);
}
Widget::~Widget()
{
}
void Widget::changeEvent(QEvent* e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui()->retranslateUi(this);
break;
default:
break;
}
}
Предупреждения компилятора
Выполняется сборка проекта q_property_widget...
Запускается: /usr/bin/make clean -w
make: Вход в каталог `/home/sabrog/work/q_property_widget'
make: *** Нет правила для сборки цели `clean'. Останов.
make: Выход из каталога `/home/sabrog/work/q_property_widget'
Завершено с кодом 2.
Запускается: /opt/qtsdk-2010.02/qt/bin/qmake /home/sabrog/work/q_property_widget/q_property_widget.pro -spec linux-g++ -r CONFIG+=debug
Завершено с кодом 0.
Запускается: /usr/bin/make -w
make: Вход в каталог `/home/sabrog/work/q_property_widget'
/opt/qtsdk-2010.02/qt/bin/uic widget.ui -o ui_widget.h
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. -o main.o main.cpp
In file included from /opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer.h:52,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpixmap.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/qbrush.h:53,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpalette.h:47,
from /opt/qtsdk-2010.02/qt/include/QtGui/qwidget.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/QWidget:1,
from widget.h:4,
from main.cpp:2:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h: In member function ‘void QtSharedPointer::ExternalRefCount<T>::internalDestroy() [with T = Ui::Widget]’:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:329: instantiated from ‘bool QtSharedPointer::ExternalRefCount<T>::deref() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:380: instantiated from ‘QtSharedPointer::ExternalRefCount<T>::~ExternalRefCount() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:441: instantiated from here
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: possible problem detected in invocation of delete operator:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: invalid use of incomplete type ‘struct Ui::Widget’
widget.h:7: warning: forward declaration of ‘struct Ui::Widget’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. -o widget.o widget.cpp
/opt/qtsdk-2010.02/qt/bin/moc -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. widget.h -o moc_widget.cpp
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. -o moc_widget.o moc_widget.cpp
In file included from /opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer.h:52,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpixmap.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/qbrush.h:53,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpalette.h:47,
from /opt/qtsdk-2010.02/qt/include/QtGui/qwidget.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/QWidget:1,
from widget.h:4,
from moc_widget.cpp:10:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h: In member function ‘void QtSharedPointer::ExternalRefCount<T>::internalDestroy() [with T = Ui::Widget]’:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:329: instantiated from ‘bool QtSharedPointer::ExternalRefCount<T>::deref() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:380: instantiated from ‘QtSharedPointer::ExternalRefCount<T>::~ExternalRefCount() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:441: instantiated from here
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: possible problem detected in invocation of delete operator:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: invalid use of incomplete type ‘struct Ui::Widget’
widget.h:7: warning: forward declaration of ‘struct Ui::Widget’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
g++ -Wl,-rpath,/opt/qtsdk-2010.02/qt/lib -o q_property_widget main.o widget.o moc_widget.o -L/opt/qtsdk-2010.02/qt/lib -lQtGui -L/opt/qtsdk-2010.02/qt/lib -L/usr/X11R6/lib -lQtCore -lpthread
make: Выход из каталога `/home/sabrog/work/q_property_widget'
Завершено с кодом 0.