Это упрощение приложения, которое я написал.Приложение PySide аварийно завершает работу при настройке нового виджета на QScrollArea
Главное окно приложения имеет кнопку и флажок. Флажок находится внутри QScrollArea (через виджет). Флажок имеет число, указывающее, сколько раз этот флажок был создан. Нажав на кнопку, вы откроете диалоговое окно с кнопкой обновления.
Нажав на кнопку обновления, вы установите новый виджет в область прокрутки с новым флажком.
Флажок имеет контекстное меню, открывающее тот же диалог. Однако, когда виджет создается с помощью диалогового окна, запускаемые в контекстном меню флажком сбой приложения со следующей ошибкой:
2016-08-03 09:22:00.036 Python[17690:408202] modalSession has been exited prematurely - check for a reentrant call to endModalSession:
Python(17690,0x7fff76dcb300) malloc: * error for object 0x7fff5fbfe2c0: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug
Катастрофа не происходит при нажатии на кнопку, чтобы открыть диалоговое окно и нажмите «Обновить» в диалоговом окне.
Аварийное происшествие происходит как на Mac, так и на Windows. Я использую Python 2.7.10 с PySide 1.2.4
#!/usr/bin/env python
import sys
from itertools import count
from PySide import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.centralwidget = QtGui.QWidget(parent=self)
self.open_diag_btn = QtGui.QPushButton('Open dialog', parent=self)
self.open_diag_btn.clicked.connect(self.open_dialog)
self.scroll_widget = QtGui.QScrollArea(parent=self)
layout = QtGui.QGridLayout(self.centralwidget)
layout.addWidget(self.scroll_widget)
layout.addWidget(self.open_diag_btn)
self.setCentralWidget(self.centralwidget)
self.set_scroll_widget()
def open_dialog(self):
dialog = Dialog(parent=self)
dialog.refresh.connect(self.set_scroll_widget) # Connecting the signal from the dialog to set a new widget to the scroll area
dialog.exec_()
# Even if I call the function here, after the dialog was closed instead of using the signal above the application crashes, but only via the checkbox
# self.set_scroll_widget()
def set_scroll_widget(self):
"""Replacing the widget of the scroll area with a new one.
The checkbox in the layout of the widget has an class instance counter so you can see how many times the checkbox was created."""
widget = QtGui.QWidget()
layout = QtGui.QVBoxLayout(widget)
widget.setLayout(layout)
open_diag_check = RefreshCheckbox(parent=self)
open_diag_check.do_open_dialog.connect(self.open_dialog) # Connecting the signal to open the dialog window
layout.addWidget(open_diag_check)
self.scroll_widget.setWidget(widget)
class RefreshCheckbox(QtGui.QCheckBox):
"""A checkbox class that has a context menu item which emits a signal that eventually opens a dialog window"""
do_open_dialog = QtCore.Signal()
_instance_counter = count(1)
def __init__(self, *args, **kwargs):
super(RefreshCheckbox, self).__init__(unicode(self._instance_counter.next()), *args, **kwargs)
self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
action = QtGui.QAction(self)
action.setText("Open dialog")
action.triggered.connect(self.emit_open_dialog)
self.addAction(action)
def emit_open_dialog(self):
self.do_open_dialog.emit()
class Dialog(QtGui.QDialog):
"""A dialog window with a button that emits a refresh signal when clicked.
This signal is used to call MainWindow.set_scroll_widget()"""
refresh = QtCore.Signal()
def __init__(self, *args, **kwargs):
super(Dialog, self).__init__(*args, **kwargs)
self.refresh_btn = QtGui.QPushButton('Refresh')
self.refresh_btn.clicked.connect(self.do_refresh)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.refresh_btn)
def do_refresh(self):
self.refresh.emit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
mySW = MainWindow()
mySW.show()
mySW.raise_()
app.exec_()
Замена dialog.exec_() с помощью show() разрешает сбой. Другие комментарии также полезны. Благодаря! – Nir