Details
-
Bug
-
Resolution: Invalid
-
P2: Important
-
None
-
6.4.1
-
None
-
This happens on every machine, os and python version i tested on. It should crash on everything.
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())