文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

pyqt 显示图片的若干方法

2023-09-21 12:13

关注

date: 2022-11-30 14:23
status: public
title: ‘pyqt 显示图片的若干方法’


单张图片

使用lable 显示图片

特点是最简单,但功能也最少。

#!/usr/bin/env python# -*- coding: utf-8 -*-import sysfrom PyQt5.QtGui import QPixmapfrom PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QLabelclass ImageLabel(QWidget):    def __init__(self, parent=None):        super().__init__(parent)        self.resize(600, 400)        self.setWindowTitle("label image")        pix = QPixmap(r'C:\fruits.jpg')        label = QLabel(self)        label.setPixmap(pix)        label.setScaledContents(True)  # 自适应QLabel大小        layout = QVBoxLayout()        layout.addWidget(label)        self.setLayout(layout)if __name__ == '__main__':    app = QApplication(sys.argv)    mainWidget = ImageLabel()    mainWidget.show()    sys.exit(app.exec_())

使用pyqtgraph 控件显示图片

来源 【PyQtGraph】显示图像
特点 可以对图片进行缩放操作,继承了pyqtgraph 的一些特点功能。

"""安装依赖库:1. Pillow2. PySide23. PyQtGraphfrom https://blog.csdn.net/zhy29563/article/details/119754910"""import sysimport numpy as npimport pyqtgraph as pgfrom PIL import Imagefrom PyQt5.QtWidgets import QApplication, QVBoxLayout, QPushButton, QWidget, QFileDialogfrom pyqtgraph import ImageView# 设置 PyQtGraph 显示配置######################################################################################################################### 设置显示背景色为白色,默认为黑色pg.setConfigOption('background', 'w')# 设置显示前景色为黑色,默认为灰色pg.setConfigOption('foreground', 'k')# 设置图像显示以行为主,默认以列为主pg.setConfigOption('imageAxisOrder', 'row-major')class PyQtGraphicDemo(QWidget):    def __init__(self, parent=None):        super(PyQtGraphicDemo, self).__init__(parent)        self.resize(600, 400)        # 图像显示控件        self.graphicsView = ImageView(self)        # 隐藏直方图,菜单按钮,ROI        self.graphicsView.ui.histogram.hide()        self.graphicsView.ui.menuBtn.hide()        self.graphicsView.ui.roiBtn.hide()        image = Image.open(r'C:\fruits.jpg')        if image is not None:            # 如果之前未设置显示选项以行为主,这里需要对显示图像进行转置            self.graphicsView.setImage(np.array(image))        self.verticalLayout = QVBoxLayout(self)        self.verticalLayout.addWidget(self.graphicsView)        # 设置窗口布局        self.setLayout(self.verticalLayout)if __name__ == '__main__':    app = QApplication(sys.argv)    window = PyQtGraphicDemo()    window.show()    sys.exit(app.exec_())

多张图片

使用scrollArea 显示多张图片

来源:PyQt5-使用scrollArea实现图片查看器功能

特点是当窗口大小小于scrollArea 区域大小时有滑动条显示,可以拖动滑动条滑动界面。

但是这份代码有个缺点,就是当窗口大小大于scrollArea 区域大小时,你会发现scrollArea 以外的区域是空白的,也就是scrollArea 是固定大小的,区域外不会显示内容。注释掉 self.setFixedSize(850, 600) 可以测试看到。
这份代码的显示原理大致如下:创建一个scrollArea控件,对多张图像依次执行下面循环的操作:1. 创建一个label 显示image;2. label 添加到 一个QVBoxLayout 中,3. QVBoxLayout 作为一个临时的QWidget layout,4. 移动这个临时的 QWidget 到指定坐标。emmm 就不是很优雅。

# from https://blog.csdn.net/HG0724/article/details/116702824import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import *from PyQt5.uic import loadUiclass Picture(QMainWindow):    def __init__(self, parent=None, url=None):        super().__init__(parent)        self.url = url        self.ui()    def ui(self):        loadUi('./show_pic.ui', self)        # self.setFixedSize(850, 600)        total = len(self.url)        self.qw = QWidget()        if total % 5 == 0:            rows = int(total / 5)        else:            rows = int(total / 5) + 1        self.qw.setMinimumSize(850, 230 * rows)        for i in range(total):            photo = QPixmap(self.url[i])            # print('photo:',photo)            # photo.loadFromData(req.content)            width = photo.width()            height = photo.height()            print('width:', width, '      ', 'height:', height)            if width == 0 or height == 0:                continue            tmp_image = photo.toImage()  # 将QPixmap对象转换为QImage对象            size = QSize(width, height)            # photo.convertFromImage(tmp_image.scaled(size, Qt.IgnoreAspectRatio))            photo = photo.fromImage(tmp_image.scaled(size, Qt.IgnoreAspectRatio))            # 为每个图片设置QLabel容器            label = QLabel()            label.setFixedSize(150, 200)            label.setStyleSheet("border:1px solid gray")            label.setPixmap(photo)            label.setScaledContents(True)  # 图像自适应窗口大小            vl = QVBoxLayout()            vl.addWidget(label)            tmp = QWidget(self.qw)            tmp.setLayout(vl)            tmp.move(160 * (i % 5), 230 * int(i / 5))        self.scrollArea.setWidget(self.qw)  # 和ui文件中名字相同if __name__ == '__main__':    app = QApplication(sys.argv)    # 这是我的文件夹中图片的路径    import glob    url = glob.glob(r"C:\waDump\*.jpg")    pic = Picture(url=url)    pic.show()    sys.exit(app.exec_())

使用scrollArea + gridLayout 显示多张图片

可以缩放窗口,图像可以随着窗口变化,但只是图像间距拉伸,每行的图片数量没有变化

# -*- coding: utf-8 -*-import globimport timefrom PyQt5 import QtWidgetsfrom PyQt5.QtCore import QSize, Qtfrom PyQt5.QtGui import QPixmapfrom PyQt5.QtWidgets import QApplication, QLabel, QGridLayoutclass Picture(QtWidgets.QWidget):    def __init__(self, parent=None):        super(Picture, self).__init__(parent)        print('Picture init')        self.setWindowTitle('All Images')        self.resize(800, 600)        # ui components        self.scrollArea = QtWidgets.QScrollArea()        self.scrollArea.setWidgetResizable(True)        self.scrollAreaWidgetContents = QtWidgets.QWidget()        # self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")        self.scrollArea.setWidget(self.scrollAreaWidgetContents)        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents)        self.v_layout = QtWidgets.QVBoxLayout(self)        self.v_layout.addWidget(self.scrollArea)        self.setLayout(self.v_layout)        # vars        self.max_columns = 5    def load_images(self, paths):        print('load images --start')        total = len(paths)        col = 0        row = 0        for i in range(total):            self.max_columns = total if total < 5 else 5            photo = QPixmap(paths[i])            width = photo.width()            height = photo.height()            if width == 0 or height == 0:                continue            tmp_image = photo.toImage()  # 将QPixmap对象转换为QImage对象            size = QSize(width, height)            # photo.convertFromImage(tmp_image.scaled(size, Qt.IgnoreAspectRatio))            photo = photo.fromImage(tmp_image.scaled(size, Qt.IgnoreAspectRatio))            # 为每个图片设置QLabel容器            label = QLabel()            w = int(self.width() / self.max_columns * 0.8)            h = int(w * photo.height() / photo.width())            label.setFixedSize(w, h)            label.setStyleSheet("border:1px solid gray")            label.setPixmap(photo)            label.setScaledContents(True)  # 图像自适应窗口大小            self.gridLayout.addWidget(label, row, col)            # 计算下一个label 位置            if col < self.max_columns - 1:                col = col + 1            else:                col = 0                row += 1        print('load images --end')if __name__ == '__main__':    start_time = time.time()    print('main layout show')    app = QApplication([])    main_window = Picture()    main_window.show()    image_list = url = glob.glob(r"C:\waDump\*.jpg")    # 加载图像显示    main_window.load_images(image_list)    print("耗时: {:.3f}秒".format(time.time() - start_time))    app.exec_()

使用 QListWidget + 自定义的 QListWidgetItem 显示多张图片

可以缩放窗口,图像可以随着窗口重新排列,自定义的QListWidgetItem 可以灵活自定义显示样式。
代码参考这两个博客 PyQt使用笔记(六) 可多选, 有右键复制删除功能的ListWidget 2021.03.23[pyqt] 使用自定义QListWidgetItem

# -*- coding: utf-8 -*-import timefrom PyQt5 import QtWidgets, QtCore, QtGuifrom PyQt5.QtCore import QSizefrom PyQt5.QtCore import Qtfrom PyQt5.QtCore import pyqtSignalfrom PyQt5.QtGui import QCursorfrom PyQt5.QtGui import QPixmapfrom PyQt5.QtWidgets import QApplicationfrom PyQt5.QtWidgets import QMenu, QAbstractItemView, QListWidgetItem, QListViewfrom PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayoutclass ImageListWidget(QtWidgets.QListWidget):    signal = pyqtSignal(list)    def __init__(self, *args, **kwargs):        super().__init__(*args, **kwargs)        self.image_cmp_widget = None        self.single_image = None        self.setWindowTitle('All Images')        self.resize(1400, 700)        self.setContextMenuPolicy(Qt.CustomContextMenu)        # 创建QMenu信号事件        self.customContextMenuRequested.connect(self.showMenu)        self.contextMenu = QMenu(self)        self.CMP = self.contextMenu.addAction('比较')        # self.CP = self.contextMenu.addAction('复制')        self.DL = self.contextMenu.addAction('删除')        # self.CP.triggered.connect(self.copy)        self.DL.triggered.connect(self.del_text)        # 设置每个item size        self.setGridSize(QtCore.QSize(220, 190))        # 设置横向list        self.setFlow(QListView.LeftToRight)        # 设置换行        self.setWrapping(True)        # 窗口size 变化后重新计算列数        self.setResizeMode(QtWidgets.QListView.Adjust)        # 设置选择模式        self.setSelectionMode(QAbstractItemView.ExtendedSelection)        self.setIconSize(QSize(200, 150))    # 显示右键菜单    def showMenu(self, pos):        # pos 鼠标位置        # 菜单显示前,将它移动到鼠标点击的位置        self.contextMenu.exec_(QCursor.pos())  # 在鼠标位置显示    # 获取选择行的内容    def selected_text(self):        try:            selected = self.selectedItems()            texts = ''            for item in selected:                if texts:                    texts = texts + '\n' + item.text()                else:                    texts = item.text()        except BaseException as e:            print(e)            return        print('selected_text texts', texts)        return texts    def copy(self):        text = self.selected_text()        if text:            clipboard = QApplication.clipboard()            clipboard.setText(text)    def del_text(self):        try:            index = self.selectedIndexes()            row = []            for i in index:                r = i.row()                row.append(r)            for i in sorted(row, reverse=True):                self.takeItem(i)        except BaseException as e:            print(e)            return        self.signal.emit(row)    def mouseDoubleClickEvent(self, e: QtGui.QMouseEvent) -> None:        super().mouseDoubleClickEvent(e)        print('double click')        selected = self.selectedItems()        img_path = ''        for item in selected:            img_path = item.image_path()        if len(img_path) > 0:            # 打开新窗口显示单张图片            # self.single_image = SingleImageView(image=img_path, background=Qt.white)            # self.single_image.show()            pass        pass    def load_images(self, paths):        for i in range(len(paths)):            img_item = ImageQListWidgetItem("dump image ***", paths[i])            self.addItem(img_item)            self.setItemWidget(img_item, img_item.widget)            # 刷新界面            QApplication.processEvents()# 自定义的item 继承自QListWidgetItemclass ImageQListWidgetItem(QListWidgetItem):    def __init__(self, name, img_path):        super().__init__()        self.img_path = img_path        # 自定义item中的widget 用来显示自定义的内容        self.widget = QWidget()        # 用来显示name        self.nameLabel = QLabel()        self.nameLabel.setText(name)        # 用来显示avator(图像)        self.avatorLabel = QLabel()        # 设置图像源 和 图像大小        img_obg = QPixmap(img_path)        width = img_obg.width()        height = img_obg.height()        scale_size = QSize(200, 150)        if width < height:            scale_size = QSize(150, 200)        self.avatorLabel.setPixmap(QPixmap(img_path).scaled(scale_size))        # 图像自适应窗口大小        self.avatorLabel.setScaledContents(True)        # 设置布局用来对nameLabel和avatorLabel进行布局        self.hbox = QVBoxLayout()        self.hbox.addWidget(self.avatorLabel)        self.hbox.addWidget(self.nameLabel)        self.hbox.addStretch(1)        # 设置widget的布局        self.widget.setLayout(self.hbox)        # 设置自定义的QListWidgetItem的sizeHint,不然无法显示        self.setSizeHint(self.widget.sizeHint())    def image_path(self):        return self.img_pathif __name__ == '__main__':    print('main layout show')    now = time.time()    app = QApplication([])    main_window = ImageListWidget()    main_window.show()    image_list = ['icon.jpg', 'icon.jpg', 'icon.jpg']    # 数据扩充    image_list = image_list + image_list + image_list + image_list    main_window.load_images(image_list)    # 绑定点击槽函数 点击显示对应item中的name    main_window.itemClicked.connect(lambda item: print('clicked item label:', item.nameLabel.text()))    print("ImageListWidget 耗时: {:.2f}秒".format(time.time() - now))    app.exec_()

来源地址:https://blog.csdn.net/aaa111/article/details/128490906

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯