Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-665

QWidgetItem deletion segfaults in QLayout.addChildWidget

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • None
    • 1.2.x, 5.9
    • PySide, Shiboken
    • Windows
      PySide2-5.9.0a1.dev1526391739-5.9.6
      Python 2.7
    • 27cc05eae297bf4a469428629394c755c76af858 (pyside/pyside-setup/5.15)

    Description

      Preface

      I have an adaption of the Qt Flow Layout Example (http://doc.qt.io/qt-5/qtwidgets-layouts-flowlayout-example.html) which works fine on its own.

      I added more methods for convenient layout management like insertWidget. I took a look at QBoxLayout in the Qt source to have a reference of what the implementation should be. I firmly believe that there is nothing wrong with my code, and the fact that it is working correctly if I use PyQt4 confirms it.

      The problem

      When I implement the insertWidget method I must create a QWidgetItem to wrap the widget in a QLayoutItem. The Qt source uses the QLayoutPrivate::createWidgetItem method which is private as its name states, so I cannot use that. Not being able to use it should not be a problem normally since it only returns a QWidgetItem and does nothing else.

      However, there is an issue with the QWidgetItems that I create on the Python side, that makes the sample code crash. Creating and using the QWidgetItems seem to work but deleting them on the C++ side does not.

      By logging the calls to virtual methods I see that QLayout.addChildWidget calls removeWidgetRecursively and that will crash on the line "delete lay->takeAt( i);".

      If I do not call the QLayout.addChildWidget method but delete the QWidgetItem on the Python side with shiboken(2).delete it works. So deleting the QWidgetItem, that had been created in Python, on the C++ side has some issue.

      Sample code

      I attached a smaller version of my code. The buttons are in the flow layout and clicking them moves them to the first place with insertWidget(0, w). You can decide which binding you use by uncommenting/commenting the desired block. Setting the config variable called "DELETE_QWIDGETITEMS_ON_PYTHON_SIDE" to True makes a hacky demonstration that deleting the QWidgetItems on the Python side works.

      Attachments

        1. customLayoutIssue.py
          6 kB
        2. pyside665_stack.txt
          17 kB
        3. pyside665.py
          6 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            kleint Friedemann Kleint
            myusername8 Nándor Mátravölgyi
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes