I have a simple application that I'm writing using PyQt 4 that includes a MainWindow that consists of a QMdiArea. When the user starts a new session (new experiment), two windows are generated. The user can also select from a list of analysis modules to also run.
I do not want any duplicates of any windows to be allowed (i.e., in the example code below the user can only have one file_tree_window, one data_plot_window, and/or one cell_monitor_window).
So, for example, if the user selects "New Experiment" once, two windows are generated. If he/she then selects "New Experiment" again, those original two windows should be closed and two new ones opened. The same is true for the any of the "Analysis Modules." (i.e. selecting one that is already open will cause the open one to close and a new one to open).
I'm having trouble generating this functionality though.
First off, code:
class MainWindow(QtGui.QMainWindow):
def __init__(self, model):
super().__init__()
self.resize(1400, 800)
self.model = model
menubar = self.menuBar()
new_experiment_action = QtGui.QAction("New Experiment", self)
new_experiment_action.triggered.connect(self.setup_new_experiment)
file_menu = menubar.addMenu("File")
file_menu.addAction(new_experiment_action)
cell_health_action = QtGui.QAction("Cell Health Monitor", self)
cell_health_action.triggered.connect(self.setup_cell_health_window)
analysis_menu = menubar.addMenu("Analysis Modules")
analysis_menu.addAction(cell_health_action)
self.file_tree = None
self.file_tree_window = None
self.data_plot = None
self.data_plot_window = None
self.cell_health = None
self.cell_health_window = None
self.mdi = QtGui.QMdiArea()
self.setCentralWidget(self.mdi)
def setup_new_experiment(self):
self.mdi.closeAllSubWindows()
self.file_tree = FileTree(self.model)
self.file_tree.setMinimumSize(QtCore.QSize(200, 300))
self.data_plot = DataPlot(self.model)
self.data_plot.setMinimumSize(self.size()*.4)
self.file_tree_window = self.mdi.addSubWindow(self.file_tree)
self.file_tree_window.show()
self.data_plot_window = self.mdi.addSubWindow(self.data_plot)
self.data_plot_window.show()
def setup_cell_health_window(self):
if self.cell_health_window:
self.mdi.removeSubWindow(self.cell_health_window)
self.cell_health = CellHealthMonitor(self.model)
self.cell_health.setMinimumSize(self.size()*.3)
self.cell_health_window = self.mdi.addSubWindow(self.cell_health)
self.cell_health_window.show()
This doesn't work in a number of ways:
- If I open a "Cell Health Monitor" window, close it, and try to re-open it, Python crashes
- If I have a "Cell Health Monitor" window open, and then try to start a "New Experiment", followed by opening a "Cell Health Monitor" window, Python crashes
I have tried to use remove() instead of close():
i.e.:
def setup_new_experiment(self):
for window in self.mdi.subWindowList():
self.mdi.removeSubWindow(window)
self.file_tree = FileTree(self.model)
self.file_tree.setMinimumSize(QtCore.QSize(200, 300))
self.data_plot = DataPlot(self.model)
self.data_plot.setMinimumSize(self.size()*.4)
self.file_tree_window = self.mdi.addSubWindow(self.file_tree)
self.file_tree_window.show()
self.data_plot_window = self.mdi.addSubWindow(self.data_plot)
self.data_plot_window.show()
def setup_cell_health_window(self):
if self.cell_health_window:
self.mdi.removeSubWindow(self.cell_health_window)
self.cell_health = CellHealthMonitor(self.model)
self.cell_health.setMinimumSize(self.size()*.3)
self.cell_health_window = self.mdi.addSubWindow(self.cell_health)
self.cell_health_window.show()
Depending on the series of actions Python either crashes or I get one of the following two error messages:
(this one is actually just a warning):
QMdiArea::removeSubWindow: window is not inside workspace
or
Traceback (most recent call last):
File "MainWindow.py", line 61, in setup_cell_health_window
self.mdi.removeSubWindow(self.cell_health_window)
RuntimeError: wrapped C/C++ object of type QMdiSubWindow has been deleted
I'm at a loss with regards to what to do differently to remove a subwindow without producing these issues.
Thanks