简体   繁体   中英

How to adjust the size of picture in QLabel?

Due to the huge size of picture, they can't be scaled based on the designed stretch in QLabel.

Here is my code below:


class goShow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initGUI()
        self.filePath = os.path.dirname(__file__)

    def initGUI(self):
        # self.setAcceptDrops(True)
        # self.resize(800, 600)
        widget = QWidget()
        self.setCentralWidget(widget)


        self.resTable = QTableWidget()
        # self.dotPlot = PictureLabel('****')
        self.dotPlot = QLabel()
        # self.dotPlot.setStyleSheet("background: rgb(255, 0, 0)")
        self.barPlot = QLabel()
        # self.barPlot.setStyleSheet("background: rgb(0, 255, 0)")

        layout = QVBoxLayout()
        widget.setLayout(layout)
        self.mainLayout = layout

        self.mainLayout.addWidget(self.resTable, stretch=4)
        self.mainLayout.addWidget(self.dotPlot,stretch=1)
        self.mainLayout.addWidget(self.barPlot,stretch=1)

        self.show()

    def showTable(self, input):
        #show talbe
        dim = input.shape
        self.resTable.setRowCount(dim[0])
        self.resTable.setColumnCount(dim[1])

        for i in range(int(dim[0])):
            for j in range(int(dim[1])):
                print(i, j)
                self.resTable.setItem(i, j, QTableWidgetItem(str(input.iloc[i, j])))

    def showDotPlot(self):
        dotPng = QPixmap(os.path.join('F:\\job\\projects\\snpExplore\\test\\res_temp',"dotplot.png"))
        self.dotPlot.setPixmap(dotPng)
        self.dotPlot.setScaledContents(True)

    def showBarPlot(self):
        # show barplot
        barPng = QPixmap(os.path.join('F:\\job\\projects\\snpExplore\\test\\res_temp',"barplot.png"))
        self.barPlot.setPixmap(barPng)
        self.barPlot.setScaledContents(True)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = goShow()
    goResTable = pd.read_csv("F:\\job\\projects\\snpExplore\\test\\res_temp\\go.csv", header=0)
    w.showTable(goResTable)
    w.showBarPlot()
    w.showDotPlot()
    sys.exit(app.exec_())

Here is the obtained picture:

在此处输入图片说明

the second and third picture are too huge, and making the first table much small. But I want the proportion of widget size is 4:1:1, respectively.

If there is no minimium size set for the label, the pixmap size will be always used instead. To avoid that, you could just set an arbitrary minimum size:

    def showDotPlot(self):
        dotPng = QPixmap('big1.jpg')
        self.dotPlot.setPixmap(dotPng)
        self.dotPlot.setMinimumSize(1, 1)
        self.dotPlot.setScaledContents(True)

Unfortunately, this will result in a stretched image:

拉伸图像不好!

In this case, the only alternative is subclassing.
In this example I'm inheriting from QLabel, but if you don't need all the features that class provides, using a standard QWidget is enough (but you may need to add methods for setting the pixmap and the alignment).

class ScaledPixmapLabel(QLabel):
    scaled = None
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # if no minimum size is set, it will always use the image size
        self.setMinimumSize(1, 1)

    def resizeEvent(self, event):
        if self.pixmap() and not self.pixmap().isNull():
            self.scaled = self.pixmap().scaled(
                self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)

    def paintEvent(self, event):
        if self.pixmap() and not self.pixmap().isNull():
            if not self.scaled:
                self.scaled = self.pixmap().scaled(
                    self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)

            # the available rectangle
            available = self.rect()
            # the pixmap rectangle that will be used as a reference to paint into
            rect = self.scaled.rect()

            # move to the center of the available rectangle
            rect.moveCenter(available.center())
            # then move the rectangle according to the alingment
            align = self.alignment()
            if align & Qt.AlignLeft:
                rect.moveLeft(available.left())
            elif align & Qt.AlignRight:
                rect.moveRight(available.right())
            if align & Qt.AlignTop:
                rect.moveTop(available.top())
            elif align & Qt.AlignBottom:
                rect.moveBottom(available.bottom())

            qp = QPainter(self)
            qp.drawPixmap(rect, self.scaled)

class goShow(QMainWindow):
    def initGUI(self):
        # ...
        self.dotPlot = ScaledPixmapLabel(alignment=Qt.AlignCenter)
        self.barPlot = ScaledPixmapLabel(alignment=Qt.AlignCenter)
        # ...

    def showDotPlot(self):
        dotPng = QPixmap(os.path.join('F:\\job\\projects\\snpExplore\\test\\res_temp',"dotplot.png"))
        self.dotPlot.setPixmap(dotPng)
        # no need to set other options

长宽比不错!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM