From 676a89fcfc2190ffa50bcb4f011ca4a96a9dd653 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Thu, 8 Feb 2018 11:18:47 +0100 Subject: Fix lost reference for item delegates After setting an item delegate for columns and rows in classes that inherit from QAbstractItemView (like QTreeView) the reference was not kept, causing a segfault. This was solved by keeping the reference of the object. A test is provided. Task-number: PYSIDE-226 Task-number: PYSIDE-219 Change-Id: I43eeb6e85a37537311d838f5abb0ee1ab10ea713 Reviewed-by: Alexandru Croitor --- .../QtWidgets/typesystem_widgets_common.xml | 10 +++ sources/pyside2/tests/QtWidgets/CMakeLists.txt | 1 + sources/pyside2/tests/QtWidgets/qtreeview_test.py | 89 ++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 sources/pyside2/tests/QtWidgets/qtreeview_test.py diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml index 60bb24335..0555d9a53 100644 --- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml @@ -435,6 +435,16 @@ + + + + + + + + + + diff --git a/sources/pyside2/tests/QtWidgets/CMakeLists.txt b/sources/pyside2/tests/QtWidgets/CMakeLists.txt index af3a476b1..4efd9d803 100644 --- a/sources/pyside2/tests/QtWidgets/CMakeLists.txt +++ b/sources/pyside2/tests/QtWidgets/CMakeLists.txt @@ -120,6 +120,7 @@ PYSIDE_TEST(qtabwidget_test.py) PYSIDE_TEST(qtabwidgetclear_test.py) PYSIDE_TEST(qtextedit_test.py) PYSIDE_TEST(qtextedit_signal_test.py) +PYSIDE_TEST(qtreeview_test.py) PYSIDE_TEST(qtoolbar_test.py) PYSIDE_TEST(qtoolbox_test.py) PYSIDE_TEST(qvalidator_test.py) diff --git a/sources/pyside2/tests/QtWidgets/qtreeview_test.py b/sources/pyside2/tests/QtWidgets/qtreeview_test.py new file mode 100644 index 000000000..a731ddafa --- /dev/null +++ b/sources/pyside2/tests/QtWidgets/qtreeview_test.py @@ -0,0 +1,89 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of PySide2. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import unittest + +from PySide2.QtGui import QStandardItemModel +from PySide2.QtWidgets import QWidget, QTreeView, QVBoxLayout, QStyledItemDelegate +from helper import UsesQApplication + +class Widget(QWidget): + def __init__(self, parent=None): + QWidget.__init__(self, parent) + self.treeView = QTreeView(self) + layout = QVBoxLayout() + layout.addWidget(self.treeView) + self.setLayout(layout) + self.treeView.setModel(QStandardItemModel()) + + self.treeView.model().setHorizontalHeaderLabels(('3', '1', '5')) + +class QWidgetTest(UsesQApplication): + + def testDelegates(self): + widget = Widget() + t = widget.treeView + + # When calling setItemDelegateForColumn using a separate variable + # for the second argument (QAbstractItemDelegate), there was no problem + # on keeping the reference to this object, since the variable was kept + # alive (case A) + # Contrary, when instantiating this argument on the function call + # Using QStyledItemDelegate inside the call the reference of the + # object was lost, causing a segfault. (case B) + + # Case A + d = QStyledItemDelegate() + # Using QStyledItemDelegate from a variable so we keep the reference alive + # and we encounter no segfault. + t.setItemDelegateForColumn(0, d) + # This raised the Segmentation Fault too, because manually destroying + # the object caused a missing refrence. + del d + + # Getting the delegates + a = t.itemDelegateForColumn(0) + self.assertIsInstance(a, QStyledItemDelegate) + + # Case B + t.setItemDelegateForColumn(1, QStyledItemDelegate()) + + # Getting the delegates + b = t.itemDelegateForColumn(1) + self.assertIsInstance(b, QStyledItemDelegate) + + # Test for Rows + t.setItemDelegateForRow(0, QStyledItemDelegate()) + self.assertIsInstance(t.itemDelegateForRow(0), QStyledItemDelegate) + + # Test for general delegate + t.setItemDelegate(QStyledItemDelegate()) + self.assertIsInstance(t.itemDelegate(), QStyledItemDelegate) + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3