Home > front end >  QMdiArea, stop subwindows from leaving area
QMdiArea, stop subwindows from leaving area

Time:04-19

Is it possible to avoid the effect of the subwindow being partially obscured?

sub window is not totally visible after being dragged.

CodePudding user response:

QMdiArea automatically installs its event filter on any new QMdiSubWindow, so you can override eventFilter(), check for geometry changes, and ensure that the geometry is always within the viewport rectangle.

In the following example I created a helper function to do so, which can also be called whenever the mdi area is resized, in order to ensure that windows are always visible even when the area is resized to a size that would potentially hide windows.

class MdiFixBoundaries(QtWidgets.QMdiArea):
    def fixGeometry(self, window, viewGeo):
        winGeo = window.geometry()
        if not viewGeo.contains(winGeo):
            if winGeo.right() > viewGeo.right():
                winGeo.moveRight(viewGeo.right())
            if winGeo.x() < 0:
                winGeo.moveLeft(0)

            if winGeo.bottom() > viewGeo.bottom():
                winGeo.moveBottom(viewGeo.bottom())
            if winGeo.y() < 0:
                winGeo.moveTop(0)
            if winGeo != window.geometry():
                window.setGeometry(winGeo)
                return True
        return False

    def eventFilter(self, obj, event):
        if (event.type() == event.Move and 
            isinstance(obj, QtWidgets.QMdiSubWindow) and
            self.fixGeometry(obj, self.viewport().geometry())):
                return True
        return super().eventFilter(obj, event)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        viewGeo = self.viewport().geometry()
        for win in self.subWindowList():
            self.fixGeometry(win, viewGeo)


app = QtWidgets.QApplication([])
mdi = MdiFixBoundaries()
for i in range(3):
    test = mdi.addSubWindow(QtWidgets.QWidget())
    test.resize(320, 240)
mdi.show()
app.exec()

Note: the ifs in fixGeometry() must be kept, without any elif and in that order, otherwise you'll risk recursion in case the size of a window is bigger than the viewport.

  • Related