关闭/删除QMdiArea子窗口的正确方法?

问题描述 投票:0回答:1

我有一个使用 PyQt 4 编写的简单应用程序,其中包含一个由 QMdiArea 组成的主窗口。当用户启动新会话(新实验)时,会生成两个窗口。用户还可以从分析模块列表中进行选择来运行。

我不希望允许任何窗口有任何重复项(即,在下面的示例代码中,用户只能拥有一个 file_tree_window、一个 data_plot_window 和/或一个 cell_monitor_window)。

因此,例如,如果用户选择“新实验”一次,则会生成两个窗口。如果他/她再次选择“新实验”,则应关闭原来的两个窗口并打开两个新窗口。对于任何“分析模块”也是如此。 (即选择已打开的一个将导致打开的一个关闭并打开一个新的)。

不过,我在生成此功能时遇到了麻烦。

首先,代码:

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() 

这在很多方面都行不通:

  • 如果我打开“细胞健康监视器”窗口,请将其关闭,然后尝试 重新打开,Python崩溃了
  • 如果我打开“细胞健康监视器”窗口,然后尝试启动“新实验”,然后打开“细胞健康监视器”窗口,Python 会崩溃

我尝试使用remove()而不是close():

即:

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()

根据一系列操作,Python 要么崩溃,要么收到以下两个错误消息之一:

(这实际上只是一个警告):

QMdiArea::removeSubWindow: window is not inside workspace

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

我不知道如何以不同的方式删除子窗口而不产生这些问题。

谢谢

python qt pyqt qmdiarea
1个回答
0
投票

我有解决这个错误的方法

for j in self.mdi.subWindowList():
    if j.windowTitle() == "<Cell Health Windows Title>":
        j.close()

所以基本上,它将获取所有打开的窗口列表并检查该窗口标题是否与“细胞健康窗口”给出的标题匹配,然后它将关闭

这是此错误的重新编码解决方案

def setup_cell_health_window(self):
    for j in self.mdi_area.subWindowList():
        if j.windowTitle() == "<Cell Health Window's Title>":
            j.close()

    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()

我希望这会有所帮助 ́\(ツ)

© www.soinside.com 2019 - 2024. All rights reserved.