python - 使用 PyQt5 显示从文件中选择的多个图像但失败

我想从一个文件中选择多个图像并显示它们,但是当我单击我的选择按钮时,图像不显示。

我使用 PyQt5 中的滚动区域组件来执行此操作,但它失败了。我怎么解决这个问题?

这是我设计的一个类,其中滚动前需要计算QWdiget的高度

import sys
from PyQt5.QtWidgets import (QWidget, QLabel, QVBoxLayout, QGridLayout, QScrollArea, QApplication, QPushButton,
                             QFileDialog)
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import (Qt, QSize)

class Picture(QWidget):
    
    def __init__(self, parent=None, pwidth=980, pheight=350):
        super().__init__(parent)
        self.mywidth = pwidth
        self.myheight = pheight
        self.rowheight = 230  # the height of one row
        self.labelwidth = 180  # 
        self.labelheight = 200  # 
        self.row_picnum = 5  #  the number of picture displayed per row
        
        self.setFixedSize(pwidth, pheight)
        layout = QGridLayout()
        self.setLayout(layout)

        # init the display area
        self.sc = QScrollArea(self)
        self.qw = QWidget(self)
        self.sc.setWidget(self.qw)
        self.qw.setMinimumSize(self.mywidth, self.myheight)
        self.sc.setMinimumSize(self.mywidth, self.myheight)

        btn = QPushButton(self)
        btn.clicked.connect(self.showimage)

     def showimage(self):
        imgName, imgType = QFileDialog.getOpenFileNames(self)
        print(imgName)

        image_address = imgName
        # get the number of image
        if image_address is not None:
            total = len(image_address)
        else:
            total = 0
        
        #  calculate the row number needed
        print(total)
        if total % self.row_picnum == 0:
            rows = int(total / self.row_picnum)
        else:
            rows = int(total / self.row_picnum) + 1

        # display the image one by one
        for i in range(total):
            # set the image
            per_picture = image_address[i]
            photo = QPixmap(per_picture)
            width = photo.width()
            height = photo.height()
            tmp_image = photo.toImage()
            size = QSize(width, height)
            photo.convertFromImage(tmp_image.scaled(size, Qt.IgnoreAspectRatio))

            #  init the widget used by image
            tmp = QWidget(self.qw)
            vl = QVBoxLayout()

            # use the label to display image
            label = QLabel()
            label.setFixedSize(self.labelwidth, self.labelheight)
            label.setStyleSheet("border:1px solid gray")  # 设置每个标签的样式
            label.setPixmap(photo)
            label.setScaledContents(True)
        
            vl.addWidget(label)

            tmp.setLayout(vl)
            tmp.move(190 * (i % self.row_picnum), self.rowheight * int(i / self.row_picnum))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    pic = Picture()
    pic.show()
    sys.exit(app.exec_())

回答1

您的用户界面存在一些问题。首先没有布局,你初始化一个,但你从来没有添加任何东西,所以你所有的小部件都只是浮动到屏幕的左上角。其次,您将 Main QWidget、滚动区域和内部滚动区域设置为相同的高度和宽度,这是不可能的,因为它们彼此嵌套。最后,当您创建图像标签时。您为它们创建了一个布局和小部件,但仅此而已,因此它们要么在下一个循环中被覆盖,要么它们也只是浮动的。

下面是一个示例,说明您可以对布局执行哪些操作以至少使图像出现在小部件中。它至少应该为您指明正确的方向。

import sys
from PyQt5.QtWidgets import (QWidget, QLabel, QVBoxLayout, QGridLayout, QScrollArea, QApplication, QPushButton, QHBoxLayout,
                             QFileDialog)
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import (Qt, QSize)

class Picture(QWidget):

    def __init__(self, parent=None, pwidth=980, pheight=350):
        super().__init__(parent)
        self.mywidth = pwidth
        self.myheight = pheight
        self.rowheight = 230  # the height of one row
        self.labelwidth = 180  #
        self.labelheight = 200  #
        self.row_picnum = 5  #  the number of picture displayed per row

        self.setFixedSize(pwidth, pheight)
        layout = QGridLayout()
        self.setLayout(layout)

        # init the display area
        self.sc = QScrollArea(self)
        self.sc_layout = QHBoxLayout()
        self.sc.setLayout(self.sc_layout)
        # self.sc.setMinimumSize(self.mywidth, self.myheight)
        btn = QPushButton(self)
        btn.clicked.connect(self.showimage)
        layout.addWidget(self.sc, 0, 0)
        layout.addWidget(btn, 1, 0)

    def showimage(self):
        imgName, imgType = QFileDialog.getOpenFileNames(self)
        print(imgName)

        image_address = imgName
        # get the number of image
        if image_address is not None:
            total = len(image_address)
        else:
            total = 0

        #  calculate the row number needed
        print(total)
        if total % self.row_picnum == 0:
            rows = int(total / self.row_picnum)
        else:
            rows = int(total / self.row_picnum) + 1

        # display the image one by one
        for i in range(total):
            # set the image
            per_picture = image_address[i]
            photo = QPixmap(per_picture)
            width = photo.width()
            height = photo.height()
            tmp_image = photo.toImage()
            size = QSize(width, height)
            photo.convertFromImage(tmp_image.scaled(size, Qt.IgnoreAspectRatio))
            tmp = QWidget(self)
            tmp_layout = QVBoxLayout()
            tmp.setLayout(tmp_layout)
            # use the label to display image
            label = QLabel()
            label.setFixedSize(self.labelwidth, self.labelheight)
            label.setStyleSheet("border:1px solid gray")  # 设置每个标签的样式
            label.setPixmap(photo)
            label.setScaledContents(True)
            self.sc_layout.addWidget(tmp)
            tmp_layout.addWidget(label)
            tmp.move(190 * (i % self.row_picnum), self.rowheight * int(i / self.row_picnum))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    pic = Picture()
    pic.show()
    sys.exit(app.exec_())

相似文章

最新文章