Is it possible to avoid the effect of the subwindow being partially obscured?
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 if
s 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.