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

Pyside will make the python garbage collector segfault with this code

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • P2: Important
    • None
    • 6.4.1
    • PySide
    • None
    • This happens on every machine, os and python version i tested on. It should crash on everything.
    • Linux/Wayland, Linux/X11, Windows

    Description

      I came across this bug when i was working on my project.
      Basically you have to do this:
      1. Create a custom QToolButton class that stores a variable which you give at init
      2. Create a custom QFrame class which has a QFormLayout as its layout, make it have an empty function `somefunction(self)`. At init, add a row to the layout with a QPushButton which executes the function named `self.add`, and make a `add` function which makes a QHBoxLayout, adds the custom toolbutton with the `self.somefunction` and parent `None`, and then add a row to the QFormLayout with the QHBoxLayout

      3. In the main window class, make a QFrame and a QVBoxLayout, add the custom QFrame to the layout, set the QFrame layout to the QVBoxLayout, and set central widget to the QFrame. Then make a function names `deletewidgets(self)` which sets every QVBoxLayout's widget's parent to None, and then do gc.collect() (this part will do the segfault). Then at init again, make a QPushButton that executes the `self.deletewidgets` function.
      4. Run the program, press the add button, then the delete button, and the program will segfault.

      Here is code that will do this
      from PySide6.QtWidgets import QHBoxLayout, QFrame,QPushButton,QApplication,QMainWindow,QFormLayout,QVBoxLayout,QToolButton
      import sys
      import gc

      class Button(QToolButton):

          def _init_(self,parent,parentfunction):
              super()._init_(parent)
              self.parentfunction = parentfunction

      class Frame(QFrame):
          def _init_(self, parent=None):
              super()._init_(parent)
              self.widgets = QFormLayout()
              plusbutton = QPushButton("press me first",None)
              plusbutton.clicked.connect(self.add)
              self.widgets.addRow("",plusbutton)

             
              self.setLayout(self.widgets)
          def add(self):
              arow = QHBoxLayout()
              arow.addWidget(Button(None,self.somefunction))
              self.widgets.addRow("button",arow)
          def somefunction(self):
              pass

      class Window(QMainWindow):
          def _init_(self):
              super()._init_()
              self.setGeometry(100,100,1280,720)
              self.viewframe = QFrame()
              self.widgets = QVBoxLayout()
              self.widgets.addWidget(Frame())
              self.viewframe.setLayout(self.widgets)
              self.setCentralWidget(self.viewframe)
              self.deletebutton = QPushButton("press me second",self)
              self.deletebutton.clicked.connect(self.deletewidgets)

              self.show()
          def deletewidgets(self):
              for i in range(self.widgets.count()):
                  todelete = self.widgets.itemAt(0).widget()
                  self.widgets.removeWidget(todelete)
                  todelete.setParent(None)
              gc.collect() # This will segfault!!!
      app = QApplication([])
      window = Window()
      sys.exit(app.exec())

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            crmaurei Cristian Maureira-Fredes
            relt relt relt
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes