PyQt5. Не отображаются субокна

Добрый день!
Разбираюсь с созданием субокон (subwindow, не знаю, как правильно перевести на русский) на PyQt. Почему-то они не отображаются при добавлении их в QMdiArea.

Прикрепляю пример программы: в главном окне есть меню с одной кнопкой - “Создать”. При нажатии на кнопку создается субокно (наследник QMdiSubWindow) и добавляется в QMdiArea главного окна. Окна вроде как создаются, print(self.mdi_area.subWindowList()) выдает непустой список, но на экране их не видно. Причем, если таким же образом создавать субокно в init(), то все нормально работает, а из других методов почему-то нет.

Можете подсказать, в чем проблема?

from PyQt5.Qt import *
from PyQt5 import QtWidgets, QtGui, QtCore
import sys

class MdiSubWindow(QMdiSubWindow):
    

    def __init__(self, text, parent=None, _size=QtCore.QSize(300, 400), 
            flags=QtCore.Qt.Widget):                       
        super(MdiSubWindow, self).__init__(parent, flags)

        self._size = _size
        self.setWindowTitle(text)
        self.setWidget(QTextEdit(text))

        self.show()

    


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        #меню
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('Окна')

        createAction = QAction('Создать', self)
        createAction.triggered.connect(self.create)

        fileMenu.addAction(createAction)


        
        

        self.mdi_area = QMdiArea()
        

        self.setCentralWidget(self.mdi_area)

    def create(self):
        self.mdi_area.addSubWindow(MdiSubWindow("name", self))
        self.show()
        print(self.mdi_area.subWindowList())

        
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    text += ''.join(traceback.format_tb(tb))
    print(text)
    QtWidgets.QMessageBox.critical(None, 'Error', text)
    sys.exit()

if __name__ == '__main__':
    sys.excepthook = log_uncaught_exceptions
    
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec()

Никогда не пользовался этими субокнами, обычно хватает просто окон )

Гугл говорит, что вроде бы надо вызвать show у субокна.

        subwindow = MdiSubWindow("name", self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

Нет, все равно не появляются. А в другой программе появляются, но отдельно от QMdiArea (то есть ими нельзя управлять через него)

Вот так заработало
Я добавил в класс главного окна поле wins - список субокон

from PyQt5.Qt import *
from PyQt5 import QtWidgets, QtGui, QtCore
import sys

class MdiSubWindow(QMdiSubWindow):
    

    def __init__(self, text, parent=None, _size=QtCore.QSize(300, 400), 
            flags=QtCore.Qt.Widget):                       
        super(MdiSubWindow, self).__init__(parent, flags)

        self._size = _size
        self.setWindowTitle(text)
        self.setWidget(QTextEdit(text))

        self.show()

    


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        #меню
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('Окна')

        createAction = QAction('Создать', self)
        createAction.triggered.connect(self.create)

        fileMenu.addAction(createAction)


        
        

        self.mdi_area = QMdiArea()

        self.wins=[]

        self.setCentralWidget(self.mdi_area)

        self.show()

    def create(self):
        self.wins.append(MdiSubWindow("name", self))
        self.mdi_area.addSubWindow(self.wins[-1])
        self.wins[-1].show()
        
        print(self.mdi_area.subWindowList())

        
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    text += ''.join(traceback.format_tb(tb))
    print(text)
    QtWidgets.QMessageBox.critical(None, 'Error', text)
    sys.exit()

if __name__ == '__main__':
    sys.excepthook = log_uncaught_exceptions
    
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec()

Непонятно почему это помочь могло :thinking:

Я сам не понимаю. Вообще эти субокна как-то странно ведут себя

Наконец, понял, в чем была ошибка: в методе create() я создавал субокно, а show() зачем-то вызывал для главного окна. То есть можно было просто вот так сделать:

    def create(self):
        win = MdiSubWindow("name", self)
        self.mdi_area.addSubWindow(win)
        win.show()

Иногда отвлечься от задачи эффективнее, чем сидеть над ней часами :laughing:

1 лайк