Создать окна с меняющимися размерами PyQt5

Как создать внутри основного окна, скажем, 3 небольших. Необходима возможность сворачивания всех трех окон или изменение их размеров, растягивая их мышкой. Какой Layout поможет это сделать?

введите сюда описание изображения


Ответы (2 шт):

Автор решения: gil9red

Можно использовать виджеты QMdiArea и QMdiSubWindow.

Пример:

from PyQt5.QtWidgets import QApplication, QMainWindow, QMdiSubWindow, QMdiArea, QTextEdit, QPushButton


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

        self.sub_window_1 = QMdiSubWindow()
        self.sub_window_1.setWidget(QTextEdit("<h1>Hello World!</h1>"))

        self.sub_window_2 = QMdiSubWindow()
        self.sub_window_2.setWidget(QPushButton('Click!'))

        self.mdi_area = QMdiArea()
        self.mdi_area.addSubWindow(self.sub_window_1)
        self.mdi_area.addSubWindow(self.sub_window_2)

        self.setCentralWidget(self.mdi_area)


if __name__ == '__main__':
    app = QApplication([])

    mw = MainWindow()
    mw.show()

    app.exec()

Скриншот:

введите сюда описание изображения

→ Ссылка
Автор решения: S. Nick

Не надо писать никакие костыли. Создайте класс (например MdiSubWindow) унаследованный от QMdiSubWindow, переопределите в нем что вам надо.

Теперь попробуйте изменять размеры окна с Title - "Hello World". Вы можете в созданный класс прописать свою логику и передавать посредством сигналов что вам нужно.

Вы также можете создать свой класс для объекта self.sub_window_2 и прописать там свою логику.

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


class MdiSubWindow(QMdiSubWindow):
    resized = QtCore.pyqtSignal(QtCore.QSize)

    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(f"<h1>{text}!</h1>"))

    def resizeEvent(self, event):
        self.w = self.size().width()
        self.h = self.size().height()
        self.resized.emit(self.size())
        super(MdiSubWindow, self).resizeEvent(event)

    def sizeHint(self):
        return self._size 


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

        self.sub_window_1 = MdiSubWindow("Hello World", self, QtCore.QSize(200, 300))  
        self.sub_window_1.resized.connect(self.sub_window_1_resized)
        self.sub_window_1.setGeometry(
            QStyle.alignedRect(
                Qt.LeftToRight,            
                Qt.AlignTop,            
                self.sub_window_1._size, 
                self.geometry()
            )
        )

        self.sub_window_2 = QMdiSubWindow()
        self.sub_window_2.setWidget(QPushButton('Click!'))
        pos = self.geometry().center() 
        self.sub_window_2.move(pos)

        self.mdi_area = QMdiArea()
        self.mdi_area.addSubWindow(self.sub_window_1)
        self.mdi_area.addSubWindow(self.sub_window_2)

        self.setCentralWidget(self.mdi_area)

    def sub_window_1_resized(self, _size):
        self.sub_window_2.resize(_size)


if __name__ == '__main__':
    app = QApplication([])
    app.setStyle("Fusion")
    mw = MainWindow()
    mw.show()
    app.exec()

введите сюда описание изображения

→ Ссылка