From 3fbe027e83648570a54c268754d37c4e99f36746 Mon Sep 17 00:00:00 2001
From: zwadar <zwadar@gmail.com>
Date: Tue, 19 Nov 2019 17:31:32 +0000
Subject: [PATCH] Removing widget from layouts wasn't deleting properly
 QWidgetItems wrappers if they were present. Ther ecould be the another object
 created at the same addess as the original C++  QWidgetItem and making PySide
 wrapper pointing to something completelly different.

---
 .../QtWidgets/glue/qlayout_help_functions.cpp | 57 +++++++++++++++++++
 .../QtWidgets/typesystem_widgets_common.xml   |  9 +++
 2 files changed, 66 insertions(+)

diff --git a/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp b/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp
index d542b88..b7c55ba 100644
--- a/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp
+++ b/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp
@@ -159,3 +159,60 @@ inline void removeLayoutOwnership(QLayout* layout, QWidget* widget)
             removeLayoutOwnership(layout, item);
     }
 }
+
+inline bool findWidgetItemRecursivelly(QLayoutItem* li, QWidget* w)
+{
+	QLayout *lay = li->layout();
+	if (!lay)
+		return false;
+	int i = 0;
+	QLayoutItem *child;
+	while ((child = lay->itemAt(i))) {
+		if (child->widget() == w) {
+			SbkObject* sbkObj = Shiboken::BindingManager::instance().retrieveWrapper(child);
+			if (sbkObj)
+				Shiboken::Object::invalidate(sbkObj);
+			return true;
+		}
+		else if (findWidgetItemRecursivelly(child, w)) {
+			return true;
+		}
+		else {
+			++i;
+		}
+	}
+	return false;
+}
+
+inline void removeWidgetItemSbkObject(QWidget* w)
+{
+	QWidget *pw = w->parentWidget();
+
+	//Qt::WA_LaidOut is never reset. It only means that the widget at some point has
+	//been in a layout.
+	if (pw && w->testAttribute(Qt::WA_LaidOut)) {
+		QLayout *l = pw->layout();
+		if (l)
+			findWidgetItemRecursivelly(l, w);
+	}
+	
+}
+
+
+inline void removeWidgetItemSbkObject(QLayout* layout, QWidget* w)
+{
+	int i = 0;
+	QLayoutItem *child;
+	while ((child = layout->itemAt(i))) {
+		if (child->widget() == w) {
+			SbkObject* sbkObj = Shiboken::BindingManager::instance().retrieveWrapper(child);
+			if (sbkObj)
+				Shiboken::Object::invalidate(sbkObj);
+			return;
+		}
+		else {
+			++i;
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
index 76b3dd1..94e0080 100644
--- a/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
+++ b/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
@@ -1344,6 +1344,7 @@
     <modify-function signature="removeWidget(QWidget*)">
       <inject-code class="target" position="beginning">
         removeLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%CPPSELF, %1);
       </inject-code>
     </modify-function>
     <modify-function signature="removeItem(QLayoutItem*)">
@@ -1376,11 +1377,13 @@
     <modify-function signature="addWidget(QWidget*)">
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%1);
       </inject-code>
     </modify-function>
     <modify-function signature="addChildWidget(QWidget*)">
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%1);        
       </inject-code>
     </modify-function>
     <modify-function signature="addChildLayout(QLayout*)">
@@ -1391,6 +1394,7 @@
     <modify-function signature="setMenuBar(QWidget*)">
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%1);        
       </inject-code>
     </modify-function>
 
@@ -1436,6 +1440,7 @@
     <modify-function signature="insertWidget(int,QWidget*)">
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %2);
+        removeWidgetItemSbkObject(%2);
       </inject-code>
     </modify-function>
   </object-type>
@@ -1448,6 +1453,7 @@
     <modify-function signature="addWidget(QWidget*,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%1);
       </inject-code>
     </modify-function>
 
@@ -1460,6 +1466,7 @@
     <modify-function signature="insertWidget(int,QWidget*,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %2);
+        removeWidgetItemSbkObject(%2);      
       </inject-code>
     </modify-function>
     <modify-function signature="insertLayout(int,QLayout*,int)">
@@ -1500,6 +1507,7 @@
       </modify-argument>
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%1);        
       </inject-code>
     </modify-function>
     <modify-function signature="addWidget(QWidget*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
@@ -1508,6 +1516,7 @@
       </modify-argument>
       <inject-code class="target" position="beginning">
         addLayoutOwnership(%CPPSELF, %1);
+        removeWidgetItemSbkObject(%1);        
       </inject-code>
     </modify-function>
     <modify-function signature="addLayout(QLayout*,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
-- 
2.18.0.windows.1

