我想从一个文件中选择多个图像并显示它们,但是当我单击我的选择按钮时,图像不显示。
我使用 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_())