Drees
Drees

Reputation: 720

Center subwindows in qmdiarea

Is there an attribute to position subwindows in qmdiarea? I’m trying to center subwindow in middle of mainwindow on startup (mdiarea)

I’m working on a mcve but haven’t finished it, wanted to see if anyone has tried doing this, and how they did it

Subwindows are randomly placed on startup when initialized

class App(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent=parent)
        self.setupUi(self)
        self.screenShape = QDesktopWidget().screenGeometry()
        self.width = self.screenShape.width()
        self.height = self.screenShape.height()
        self.resize(self.width * .6, self.height * .6)
        self.new = []
#calls GUI's in other modules
        self.lw = Login()
        self.vs = VS()
        self.ms = MS()
        self.hw = HomeWindow()
        self.mw = MainWindow()
        self.ga = GA()
        self.sGUI = Settings()
# shows subwindow
        self.CreateLogin()
        self.CreateVS()
        self.CreateMS()
        self.CreateGA()
        self.CreateSettings()

    def CreateLogin(self):
        self.subwindow = QMdiSubWindow()
        self.subwindow.setWidget(self.lw)
        self.subwindow.setAttribute(Qt.WA_DeleteOnClose, True)
        self.mdiArea.addSubWindow(self.subwindow)
        self.subwindow.setMaximumSize(520, 300)
        self.subwindow.setMinimumSize(520, 300)
        self.lw.showNormal()

    def CreateVS(self):
        self.subwindow = QMdiSubWindow()
        self.subwindow.setWidget(self.vs)
        self.mdiArea.addSubWindow(self.subwindow)
        self.vs.showMinimized()

    def CreateMS(self):
        self.subwindow = QMdiSubWindow()
        self.subwindow.setWidget(self.ms)
        self.mdiArea.addSubWindow(self.subwindow)
        self.ms.showMinimized()
        self.ms.tabWidget.setCurrentIndex(0)

    def CreateGA(self):
        self.subwindow = QMdiSubWindow()
        self.subwindow.setWidget(self.ga)
        self.mdiArea.addSubWindow(self.subwindow)
        self.ga.showMinimized()
        self.subwindow.setMaximumSize(820, 650)

    def CreateSettings(self):
        self.subwindow = QMdiSubWindow()
        self.subwindow.setWidget(self.sGUI)
        self.mdiArea.addSubWindow(self.subwindow)
        self.sGUI.showMinimized()

    def CreateWindow(self):
        self.hw.pushButton.clicked.connect(self.vs.showNormal)
        self.hw.pushButton_2.clicked.connect(self.Moduleprogram)
        self.hw.pushButton_3.clicked.connect(self.ms.showNormal)
        self.hw.pushButton_4.clicked.connect(self.ga.showNormal)
        self.subwindow = QMdiSubWindow()
        self.subwindow.setWindowFlags(Qt.CustomizeWindowHint | Qt.Tool)
        self.subwindow.setWidget(self.hw)
        self.subwindow.setMaximumSize(258, 264)
        self.subwindow.move(self.newwidth*.35, self.newheight*.25)
        self.mdiArea.addSubWindow(self.subwindow)

Upvotes: 3

Views: 1622

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

In Qt the geometry is only effective when the window is visible so if you want to center something it must be in the showEvent method. On the other hand to center the QMdiSubWindow you must first get the center of the viewport of the QMdiArea, and according to that modify the geometry of the QMdiSubWindow.

Because the code you provide is complicated to execute, I have created my own code

from PyQt5 import QtCore, QtGui, QtWidgets
import random


def create_widget():
    widget = QtWidgets.QLabel(
        str(random.randint(0, 100)), alignment=QtCore.Qt.AlignCenter
    )
    widget.setStyleSheet(
        """background-color: {};""".format(
            QtGui.QColor(*random.sample(range(255), 3)).name()
        )
    )
    widget.setMinimumSize(*random.sample(range(100, 300), 2))
    return widget


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        add_button = QtWidgets.QPushButton(
            "Add subwindow", clicked=self.add_subwindow
        )
        self._mdiarea = QtWidgets.QMdiArea()

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(add_button)
        lay.addWidget(self._mdiarea)

        self._is_first_time = True

        for _ in range(4):
            self.add_subwindow()

    @QtCore.pyqtSlot()
    def add_subwindow(self):
        widget = create_widget()
        subwindow = QtWidgets.QMdiSubWindow(self._mdiarea)
        subwindow.setWidget(widget)
        subwindow.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
        subwindow.show()
        self._mdiarea.addSubWindow(subwindow)
        # self.center_subwindow(subwindow)

    def showEvent(self, event):
        if self.isVisible() and self._is_first_time:
            for subwindow in self._mdiarea.subWindowList():
                self.center_subwindow(subwindow)
            self._is_first_time = False

    def center_subwindow(self, subwindow):
        center = self._mdiarea.viewport().rect().center()
        geo = subwindow.geometry()
        geo.moveCenter(center)
        subwindow.setGeometry(geo)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter image description here

Update:

If you want the subwindow to be centered then with the following code you have to create a property center to True:

def add_subwindow(self):
    widget = create_widget()
    subwindow = QtWidgets.QMdiSubWindow(self._mdiarea)
    subwindow.setWidget(widget)
    subwindow.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
    subwindow.show()
    subwindow.setProperty("center", True) # <----
    self._mdiarea.addSubWindow(subwindow)

def showEvent(self, event):
    if self.isVisible() and self._is_first_time:
        for subwindow in self._mdiarea.subWindowList():
            if subwindow.property("center"): # <---
                self.center_subwindow(subwindow)
        self._is_first_time = False

Upvotes: 3

Related Questions