From ae998290bf1959a898faeff58b527fcfaa7e471b 2009-04-09 14:58:49 From: florianlink Date: 2009-04-09 14:58:49 Subject: [PATCH] - added hasOwner method to manage ownership more nicely - added force flag to make delete() work - added check for hasOwner git-svn-id: svn://svn.code.sf.net/p/pythonqt/code/trunk@51 ea8d5007-eb21-0410-b261-ccb3ea6e24a9 --- diff --git a/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QGraphicsItem.h b/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QGraphicsItem.h index 787d9ec..7427d86 100644 --- a/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QGraphicsItem.h +++ b/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QGraphicsItem.h @@ -37,6 +37,8 @@ enum GraphicsItemFlag{ enum GraphicsItemChange{ ItemPositionChange = QGraphicsItem::ItemPositionChange, ItemMatrixChange = QGraphicsItem::ItemMatrixChange, ItemVisibleChange = QGraphicsItem::ItemVisibleChange, ItemEnabledChange = QGraphicsItem::ItemEnabledChange, ItemSelectedChange = QGraphicsItem::ItemSelectedChange, ItemParentChange = QGraphicsItem::ItemParentChange, ItemChildAddedChange = QGraphicsItem::ItemChildAddedChange, ItemChildRemovedChange = QGraphicsItem::ItemChildRemovedChange, ItemTransformChange = QGraphicsItem::ItemTransformChange, ItemPositionHasChanged = QGraphicsItem::ItemPositionHasChanged, ItemTransformHasChanged = QGraphicsItem::ItemTransformHasChanged, ItemSceneChange = QGraphicsItem::ItemSceneChange, ItemVisibleHasChanged = QGraphicsItem::ItemVisibleHasChanged, ItemEnabledHasChanged = QGraphicsItem::ItemEnabledHasChanged, ItemSelectedHasChanged = QGraphicsItem::ItemSelectedHasChanged, ItemParentHasChanged = QGraphicsItem::ItemParentHasChanged, ItemSceneHasChanged = QGraphicsItem::ItemSceneHasChanged, ItemCursorChange = QGraphicsItem::ItemCursorChange, ItemCursorHasChanged = QGraphicsItem::ItemCursorHasChanged, ItemToolTipChange = QGraphicsItem::ItemToolTipChange, ItemToolTipHasChanged = QGraphicsItem::ItemToolTipHasChanged, ItemFlagsChange = QGraphicsItem::ItemFlagsChange, ItemFlagsHaveChanged = QGraphicsItem::ItemFlagsHaveChanged, ItemZValueChange = QGraphicsItem::ItemZValueChange, ItemZValueHasChanged = QGraphicsItem::ItemZValueHasChanged}; public slots: + bool hasOwner(QGraphicsItem* theWrappedObject) { return theWrappedObject->scene()!=NULL || theWrappedObject->parentItem()!=NULL; } + void delete_QGraphicsItem(QGraphicsItem* obj) { delete obj; } bool acceptDrops(QGraphicsItem* theWrappedObject) const; bool acceptHoverEvents(QGraphicsItem* theWrappedObject) const; diff --git a/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QTreeWidgetItem.h b/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QTreeWidgetItem.h index aac81e9..b9be275 100644 --- a/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QTreeWidgetItem.h +++ b/generated_cpp/com_trolltech_qt_gui/PythonQtWrapper_QTreeWidgetItem.h @@ -23,6 +23,8 @@ enum ItemType{ enum ChildIndicatorPolicy{ ShowIndicator = QTreeWidgetItem::ShowIndicator, DontShowIndicator = QTreeWidgetItem::DontShowIndicator, DontShowIndicatorWhenChildless = QTreeWidgetItem::DontShowIndicatorWhenChildless}; public slots: + bool hasOwner(QTreeWidgetItem* theWrappedObject) { return theWrappedObject->treeWidget()!=NULL || theWrappedObject->parent()!=NULL; } + QTreeWidgetItem* new_QTreeWidgetItem(QTreeWidget* view, QTreeWidgetItem* after, int type = Type); QTreeWidgetItem* new_QTreeWidgetItem(QTreeWidget* view, const QStringList& strings, int type = Type); QTreeWidgetItem* new_QTreeWidgetItem(QTreeWidget* view, int type = Type); diff --git a/generator/shellheadergenerator.cpp b/generator/shellheadergenerator.cpp index 739cbaa..7db6d62 100644 --- a/generator/shellheadergenerator.cpp +++ b/generator/shellheadergenerator.cpp @@ -120,6 +120,11 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } "; s << endl; } + if (meta_class->name()=="QTreeWidgetItem") { + s << "bool hasOwner(QTreeWidgetItem* theWrappedObject) { return theWrappedObject->treeWidget()!=NULL || theWrappedObject->parent()!=NULL; }" << endl; + } else if (meta_class->name()=="QGraphicsItem") { + s << "bool hasOwner(QGraphicsItem* theWrappedObject) { return theWrappedObject->scene()!=NULL || theWrappedObject->parentItem()!=NULL; }" << endl; + } AbstractMetaFunctionList functions = meta_class->queryFunctions( AbstractMetaClass::NormalFunctions | AbstractMetaClass::WasVisible | AbstractMetaClass::WasPublic diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 67612db..ab127b9 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -641,3 +641,19 @@ QObject* PythonQtClassInfo::decorator() } return _decoratorProvider; } + +bool PythonQtClassInfo::hasOwnerMethodButNoOwner(void* object) +{ + PythonQtMemberInfo info = member("hasOwner"); + if (info._type == PythonQtMemberInfo::Slot) { + void* obj = object; + bool result = false; + void* args[2]; + args[0] = &result; + args[1] = &obj; + info._slot->decorator()->qt_metacall(QMetaObject::InvokeMetaMethod, info._slot->slotIndex(), args); + return !result; + } else { + return false; + } +} diff --git a/src/PythonQtClassInfo.h b/src/PythonQtClassInfo.h index 5262f6e..5f7392d 100644 --- a/src/PythonQtClassInfo.h +++ b/src/PythonQtClassInfo.h @@ -122,6 +122,9 @@ public: //! set the parent class name of a wrapped CPP pointer void setWrappedParentClassName(const QByteArray& name) { _wrappedParentClassName = name; _parentClassInfo = NULL; _parentClassInfoResolved = false; } + //! check if the special method "hasOwner" is implemented and if it returns false, which means that the object may be destroyed + bool hasOwnerMethodButNoOwner(void* object); + private: //! resolve the parent class from either meta object or cpp parent class name void resolveParentClassInfo(); diff --git a/src/PythonQtWrapper.cpp b/src/PythonQtWrapper.cpp index 8833bb0..ce17101 100644 --- a/src/PythonQtWrapper.cpp +++ b/src/PythonQtWrapper.cpp @@ -46,16 +46,17 @@ #include "PythonQtClassInfo.h" #include "PythonQtConversion.h" -static void PythonQtWrapper_deleteObject(PythonQtWrapper* self) { +static void PythonQtWrapper_deleteObject(PythonQtWrapper* self, bool force = false) { + + // is this a C++ wrapper? if (self->_wrappedPtr) { - //mlabDebugConst("Python","c++ wrapper removed " << self->_wrappedPtr << " " << self->_obj->className() << " " << self->_info->wrappedClassName().latin1()); PythonQt::priv()->removeWrapperPointer(self->_wrappedPtr); // we own our qobject, so we delete it now: delete self->_obj; self->_obj = NULL; - if (self->_ownedByPythonQt) { + if (force || self->_info->hasOwnerMethodButNoOwner(self->_wrappedPtr) || self->_ownedByPythonQt) { int type = self->_info->metaTypeId(); if (self->_useQMetaTypeDestroy && type>=0) { // use QMetaType to destroy the object @@ -84,8 +85,8 @@ static void PythonQtWrapper_deleteObject(PythonQtWrapper* self) { PythonQt::priv()->removeWrapperPointer(self->_objPointerCopy); } if (self->_obj) { - if (self->_ownedByPythonQt) { - if (!self->_obj->parent()) { + if (force || self->_ownedByPythonQt) { + if (force || !self->_obj->parent()) { delete self->_obj; } } else { @@ -138,7 +139,7 @@ static PyObject *PythonQtWrapper_help(PythonQtWrapper* type) static PyObject *PythonQtWrapper_delete(PythonQtWrapper * self) { - PythonQtWrapper_deleteObject(self); + PythonQtWrapper_deleteObject(self, true); Py_INCREF(Py_None); return Py_None; }