import os
from PyQt5.QtWidgets import QListView, QApplication, QMainWindow, QStyledItemDelegate
from PyQt5.uic import loadUi
from PyQt5.QtCore import Qt, QSize, QFile, QPoint
from PyQt5.QtGui import QPixmap, QPainter, QStandardItemModel, QStandardItem
class BottomImageDelegate(QStyledItemDelegate):
def __init__(self, aspect_ratio=16/9):
super().__init__()
self.aspect_ratio = aspect_ratio
self.margin = 5 # 边距
def paint(self, painter, option, index):
path = index.data(Qt.UserRole + 1)
if not path or not QFile.exists(path):
return
# 获取动态尺寸
item_width = self.calculate_item_width(option.widget.width())
target_size = QSize(item_width, int(item_width / self.aspect_ratio))
# 加载并缩放图片
pixmap = QPixmap(path).scaled(
target_size,
Qt.KeepAspectRatio,
Qt.SmoothTransformation
)
# 计算绘制位置
x = option.rect.x() + (option.rect.width() - pixmap.width()) // 2
y = option.rect.y() + (option.rect.height() - pixmap.height()) // 2
# 绘制背景和图片
painter.save()
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.SmoothPixmapTransform)
painter.drawPixmap(QPoint(x, y), pixmap)
painter.restore()
def sizeHint(self, option, index):
view_width = option.widget.width()
return QSize(self.calculate_item_width(view_width),
int(self.calculate_item_width(view_width) / self.aspect_ratio))
def calculate_item_width(self, view_width):
# 根据视图宽度计算每项宽度(示例:至少显示4项)
return max(200, view_width // 4 - 2*self.margin)
class ListImageDelegate(QStyledItemDelegate):
def __init__(self, aspect_ratio=16/9):
super().__init__()
self.aspect_ratio = aspect_ratio
self.margin = 5 # 边距
def paint(self, painter, option, index):
path = index.data(Qt.UserRole + 1)
if not path or not QFile.exists(path):
return
# 获取动态尺寸
item_width = self.calculate_item_width(option.widget.width())
target_size = QSize(item_width, int(item_width / self.aspect_ratio))
# 加载并缩放图片
pixmap = QPixmap(path).scaled(
target_size,
Qt.KeepAspectRatio,
Qt.SmoothTransformation
)
# 计算绘制位置
x = option.rect.x() + (option.rect.width() - pixmap.width()) // 2
y = option.rect.y() + (option.rect.height() - pixmap.height()) // 2
# 绘制背景和图片
painter.save()
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.SmoothPixmapTransform)
painter.drawPixmap(QPoint(x, y), pixmap)
painter.restore()
def sizeHint(self, option, index):
view_width = option.widget.width()
return QSize(self.calculate_item_width(view_width),
int(self.calculate_item_width(view_width) / self.aspect_ratio))
def calculate_item_width(self, view_width):
# 根据视图宽度计算每项宽度(示例:至少显示4项)
return max(200, view_width // 4 - 2*self.margin)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
loadUi("D:/Users/W20001405/Desktop/SWBU/AI_POSE/UI/show20.ui", self)
# 初始化模型和委托
self.model = QStandardItemModel()
self.delegate = ListImageDelegate()
# 配置视图
self.listView_left.setModel(self.model)
self.listView_left.setItemDelegate(self.delegate)
# self.listView.setFlow(QListView.LeftToRight)
# self.listView.setWrapping(False)
# self.listView.setResizeMode(QListView.Adjust)
# 加载示例图片
self.load_images(["D:/Users/W20001405/Desktop/SWBU/AI_POSE/1.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/2.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/1.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/2.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/1.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/2.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/1.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/2.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/1.png",
"D:/Users/W20001405/Desktop/SWBU/AI_POSE/2.png"])
# 绑定窗口尺寸变化事件
self.resizeEvent = self.on_resize
def load_images(self, paths):
for path in paths:
item = QStandardItem()
item.setData(os.path.abspath(path), Qt.UserRole + 1)
self.model.appendRow(item)
def on_resize(self, event):
# 触发委托尺寸重计算
self.delegate = ListImageDelegate() # 重新创建委托实例
self.listView_left.setItemDelegate(self.delegate)
self.listView_left.updateGeometry()
super().resizeEvent(event)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
将以上代码解读并添加详细的注释