在QmdiArea中让子窗口居中显示

3

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

1个回答

3
在Qt中,只有当窗口可见时,几何结构才有效。因此,如果您想要居中某些内容,它必须位于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_())

在此输入图片描述

更新:

如果您想要子窗口居中,则需要将以下代码的center属性设置为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

你提供的代码是针对所有子窗口的,还是只能应用于特定的子窗口? - Drees
@Drees 你想将哪些子窗口居中于主窗口? - eyllanesc
在我提供的代码中,“self.hw”和“self.lw”是我想要居中的两个,其他的我不关心,因为它们最初是隐藏的。 - Drees
我得在我的代码上工作,我现在不在工作岗位上,所以我没有权限。看起来它应该能解决问题。 - Drees

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接