Как настроить размер картинки в QLabel? - PullRequest
0 голосов
/ 07 февраля 2020

Из-за огромного размера изображения их нельзя масштабировать на основе спроектированного растяжения в QLabel.

Вот мой код ниже:


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_())

Вот полученный изображение:

enter image description here

второе и третье изображение слишком велики, и из-за этого первый стол становится очень маленьким. Но я хочу, чтобы размер виджета составлял 4: 1: 1 соответственно.

1 Ответ

0 голосов
/ 07 февраля 2020

Если для метки не установлен минимальный размер, вместо него всегда будет использоваться размер растрового изображения. Чтобы избежать этого, вы можете просто установить произвольный минимальный размер:

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

К сожалению, это приведет к растянутому изображению:

stretched images are bad!

В этом случае единственной альтернативой является создание подклассов.
В этом примере я наследую от QLabel, но если вам не нужны все функции, предоставляемые этим классом, достаточно использовать стандартный QWidget (но вы можете нужно добавить методы для настройки растрового изображения и выравнивания).

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

aspect ratio is good!

...