How to overlay widgets in PyQt5?

2019-08-23 10:09发布

问题:

I would like to render some layouts - that groups some widgets - over a background layout that contains an image widget.

Let me explain myself with an image. The following image shows the desired output:

However, all I haven't find the way to overlay the two image widgets, and they show like this:

And this is the Python code I wrote:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtCore, Qt
import sys


class ExampleWindow(QMainWindow):
    def __init__(self, windowsize):
        super().__init__()
        self.windowsize = windowsize
        self.initUI()

    def initUI(self):
        self.setGeometry(0, 0, self.windowsize.width(), self.windowsize.height())
        self.setMaximumSize(self.windowsize.width(), self.windowsize.height())
        self.setMinimumSize(self.windowsize.width(), self.windowsize.height())
        self.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.FramelessWindowHint)

        widget = QWidget()
        self.setCentralWidget(widget)

        # Picture 1's widget
        pixmap = QPixmap('picture_1.jpg')
        pixmap = pixmap.scaledToWidth(self.windowsize.width())
        self.image = QLabel()
        self.image.setPixmap(pixmap)
        left_box = QVBoxLayout()
        left_box.setContentsMargins(0,0,0,0)
        left_box.setSpacing(0)
        left_box.setAlignment(Qt.Qt.AlignLeft)
        left_box.addWidget(self.image, 0, Qt.Qt.AlignLeft | Qt.Qt.AlignTop)

        # Picture 2's widget
        pixmap = QPixmap('picture_2.jpg')
        pixmap = pixmap.scaledToWidth(400)
        self.image2 = QLabel()
        self.image2.setPixmap(pixmap)
        right_box = QVBoxLayout()
        right_box.setContentsMargins(0, 0, 0, 0)
        right_box.setSpacing(0)
        right_box.setAlignment(Qt.Qt.AlignLeft)
        right_box.addWidget(self.image2, 0, Qt.Qt.AlignLeft | Qt.Qt.AlignBottom)

        layout_box = QHBoxLayout()
        layout_box.addLayout(left_box)
        layout_box.addLayout(right_box)

        widget.setLayout(layout_box)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    screensize = app.desktop().availableGeometry()

    ex = ExampleWindow(screensize)
    ex.show()

sys.exit(app.exec_())

Could you please help me to modify my code in order to get the widgets overlaid as shown on first image?

回答1:

Layouts are elements that manage the geometry of widgets, in your case both layouts try to occupy the largest available space. For a widget to be part of another widget there are 2 possibilities, the first is to use a layout, and the second is that the main widget is the father of the new widget, in the case of the first image we will use the first one, and for the second one we will use the second method.

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys


class ExampleWindow(QMainWindow):
    def __init__(self, windowsize):
        super().__init__()
        self.windowsize = windowsize
        self.initUI()

    def initUI(self):
        self.setFixedSize(self.windowsize)
        self.setWindowFlags(Qt.CustomizeWindowHint | Qt.FramelessWindowHint)

        widget = QWidget()
        self.setCentralWidget(widget)
        pixmap1 = QPixmap('picture_1.jpg')
        pixmap1 = pixmap1.scaledToWidth(self.windowsize.width())
        self.image = QLabel()
        self.image.setPixmap(pixmap1)

        layout_box = QHBoxLayout(widget)
        layout_box.setContentsMargins(0, 0, 0, 0)
        layout_box.addWidget(self.image)

        pixmap2 = QPixmap('picture_2.jpg')
        self.image2 = QLabel(widget)
        self.image2.setPixmap(pixmap2)
        self.image2.setFixedSize(pixmap2.size())

        p = self.geometry().bottomRight() - self.image2.geometry().bottomRight() - QPoint(100, 100)
        self.image2.move(p)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    screensize = app.desktop().availableGeometry().size()

    ex = ExampleWindow(screensize)
    ex.show()

sys.exit(app.exec_())