qmdiaarea 中的中心子窗口

Center subwindows in qmdiarea

qmdiarea 中是否有定位子窗口的属性?我试图在启动时将子窗口置于主窗口中间(mdiarea)

我正在做 mcve 但还没有完成,想看看有没有人试过这样做,他们是怎么做到的

子窗口在初始化时随机放置在启动时

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)

在 Qt 中,几何只有在 window 可见时才有效,所以如果你想居中某些东西,它必须在 showEvent 方法中。另一方面,要使 QMdiSubWindow 居中,您必须首先获取 QMdiArea 视口的中心,并根据该中心修改 QMdiSubWindow 的几何形状。

由于您提供的代码执行起来比较复杂,我已经创建了自己的代码

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

更新:

如果你想让 subwindow 居中然后用下面的代码你必须创建一个 属性 中心到 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