用 Pyqt5 打造一个精美 图片浏览器

简介: Pyqt5 是一套Qt 应用框架与 python的结合,同时支持 2.x 和 3.x。是附属于 python 一款强大的 GUI 库。本片文章写的 图片浏览程序 就是基于 pyqt5 所完成的,由于 图片预览器 中我们需要增加一些滚动滑轮,所以这里我用到的控件主要是 pyqt5的 QScrollArea ;能够伴随着图片的不断增加而增加页面空间,

前言


Pyqt5 是一套Qt 应用框架与 python的结合,同时支持 2.x 和 3.x。是附属于 python 一款强大的 GUI 库。


本片文章写的 图片浏览程序 就是基于 pyqt5 所完成的,由于 图片预览器 中我们需要增加一些滚动滑轮,所以这里我用到的控件主要是 pyqt5的 QScrollArea ;能够伴随着图片的不断增加而增加页面空间,


可以看一下最终的实现效果:

实现过程


实现这个 图片浏览程序 主要分为两大模块:界面模块 和 逻辑实现模块


界面模块


就是程序的 UI 界面,与用户交互所用到的平台;主界面是用 QWidget 开发的,界面利用垂直布局分布 ( 这里用到的是 QVBoxlayout 控件):主界面上面添加两个起始按钮(QPushbutton),界面的下面放置就是一个 QScrollArea 组件(滚动条);

class img_viewed(QWidget):
    def __init__(self,parent =None):
        super(img_viewed,self).__init__(parent)
        self.parent = parent
        self.width = 960
        self.height = 500
        self.scroll_ares_images = QScrollArea(self)
        self.scroll_ares_images.setWidgetResizable(True)
        self.scrollAreaWidgetContents = QWidget(self)
        self.scrollAreaWidgetContents.setObjectName('scrollAreaWidgetContends')
        # 进行网络布局
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents)
        self.scroll_ares_images.setWidget(self.scrollAreaWidgetContents)
        self.scroll_ares_images.setGeometry(20, 50, self.width, self.height)
        self.vertocal1 = QVBoxLayout()
        # self.meanbar = QMenu(self)
        # self.meanbar.addMenu('&菜单')
        # self.openAct = self.meanbar.addAction('&Open',self.open)
        # self.startAct =self.meanbar.addAction('&start',self.start_img_viewer)
        self.open_file_pushbutton =QPushButton(self)
        self.open_file_pushbutton.setGeometry(150,10,100,30)
        self.open_file_pushbutton.setObjectName('open_pushbutton')
        self.open_file_pushbutton.setText('打开文件夹...')
        self.open_file_pushbutton.clicked.connect(self.open)
        self.start_file_pushbutton = QPushButton(self)
        self.start_file_pushbutton.setGeometry(750, 10, 100, 30)
        self.start_file_pushbutton.setObjectName('start_pushbutton')
        self.start_file_pushbutton.setText('开始')
        self.start_file_pushbutton.clicked.connect(self.start_img_viewer)
        self.vertocal1.addWidget(self.scroll_ares_images)
if __name__ =='__main__':
    app =QApplication(sys.argv)
    windo = img_viewed()
    windo.show()
    sys.exit(app.exec_())

预览效果如下:

上面的 QScrollArea 模块内部又加了一个 QWidget 组件,因为图片分布是逐排顺序进行的,所以组件的内部利用的是网络布局分布( QGridLayout 分布控件 )


逻辑功能实现


逻辑界面已经完成,接下来就是给界面加上相应的功能:

  • 文件打开软件启动功能开发;
  • 对图片排布开发相应的功能;


文件打开 这里用到的是 QFileDialog.getExistingDirectory 控件;然后用函数进行封装起来,如果选取的文件为空,需要弹出一个提示对话框来告诉用户,选择的文件夹不合法:

    def open(self):
        file_path = QFileDialog.getExistingDirectory(self, '选择文文件夹', '/')
        if file_path ==None:
            QMessageBox.information(self,'提示','文件为空,请重新操作')
        else:
            self.initial_path =file_path#self.initial_path用来存放图片所在的文件夹

然后就是在 类的主功能函数 init 下面加上一行代码,让打开按钮对这个函数进行衔接:

self.open_file_pushbutton.clicked.connect(self.open)

然后就能达到下面的效果了:

软件启动 图片文件夹已经获取到了,接下来就是对对文件夹中的图片进行预览功能的开发:


图片布局与显示问题:图片布局就是之前提到的网络布局方式(Qgridlayout),图片显示是利用 (Qlbel控件)


  图片布局分布时,首先设定图片的固定宽度,然后根据自己设定窗口大小,进行图片        分布,每排容纳的图片数量 = 设定窗口 / 图片固定宽度;


   初始的时候把图片的所在位置都设为0,然后每当每一排的图片数量达到最大容纳数量时,就加一;

    def addImage(self, pixmap, image_id):
        #图像法列数
        nr_of_columns = self.get_nr_of_image_columns()
        #这个布局内的数量
        nr_of_widgets = self.gridLayout.count()
        self.max_columns =nr_of_columns
        if self.col < self.max_columns:
            self.col =self.col +1
        else:
            self.col =0
            self.row +=1
        print('行数为{}'.format(self.row))
        print('此时布局内不含有的元素数为{}'.format(nr_of_widgets))
        print('列数为{}'.format(self.col))
        clickable_image = QClickableImage(self.displayed_image_size, self.displayed_image_size, pixmap, image_id)
        clickable_image.clicked.connect(self.on_left_clicked)
        clickable_image.rightClicked.connect(self.on_right_clicked)
        self.gridLayout.addWidget(clickable_image, self.row, self.col)
        def loc_fil(self,stre):
      print('存放地址为{}'.format(stre))
        self.initial_path = stre
    #下面两个函数是用来接受传递信号用的;
    def geng_path(self,loc):
        print('路径为,,,,,,{}'.format(loc))
    def gen_type(self,type):
        print('图片类型为:,,,,{}'.format(type))

图片显示的话,利用的 Qpixmap 控件;这里又开发了一个类,用来传递经过处理(尺寸改变,加图片源地址) 之后的 Pixmap,用的是 pyqSignal 方法(信号传递)


QClickableImage ;这个模块主要是生成一个 QWidget : 这个 Qwidget用的是垂直布局分布,上面放的是图片,下面放的是图片的 地址 ( image_id );

class QClickableImage(QWidget):
    image_id =''
    def __init__(self,width =0,height =0,pixmap =None,image_id = ''):
        QWidget.__init__(self)
        self.layout =QVBoxLayout(self)
        self.label1 = QLabel()
        self.label1.setObjectName('label1')
        self.lable2 =QLabel()
        self.lable2.setObjectName('label2')
        self.width =width
        self.height = height
        self.pixmap =pixmap
        if self.width and self.height:
            self.resize(self.width,self.height)
        if self.pixmap:
            pixmap = self.pixmap.scaled(QSize(self.width,self.height),Qt.KeepAspectRatio,Qt.SmoothTransformation)
            self.label1.setPixmap(pixmap)
            self.label1.setAlignment(Qt.AlignCenter)
            self.layout.addWidget(self.label1)
        if image_id:
            self.image_id =image_id
            self.lable2.setText(image_id)
            self.lable2.setAlignment(Qt.AlignCenter)
            ###让文字自适应大小
            self.lable2.adjustSize()
            self.layout.addWidget(self.lable2)
        self.setLayout(self.layout)
    clicked = pyqtSignal(object)
    rightClicked = pyqtSignal(object)
    def mouseressevent(self,ev):
        print('55555555555555555')
        if ev.button() == Qt.RightButton:
            print('dasdasd')
            #鼠标右击
            self.rightClicked.emit(self.image_id)
        else:
            self.clicked.emit(self.image_id)
    def imageId(self):
        return self.image_id

当以上所有功能都已经开发完之后,接下来就是对那个 软件启动 按钮添加功能:这里做的是一个函数封装,主要实现是先递归文件夹中的每张照片,然后对每张照片利用 addImage() 函数添加到界面的相应位置。

    def start_img_viewer(self):
        if self.initial_path:
            file_path = self.initial_path
            print('file_path为{}'.format(file_path))
            print(file_path)
            img_type = 'png'
            if file_path and img_type:
                png_list = list(i for i in os.listdir(file_path) if str(i).endswith('.{}'.format(img_type)))
                print(png_list)
                num = len(png_list)
                if num !=0:
                    for i in range(num):
                        image_id = str(file_path + '/' + png_list[i])
                        print(image_id)
                        pixmap = QPixmap(image_id)
                        self.addImage(pixmap, image_id)
                        print(pixmap)
                        QApplication.processEvents()
                else:
                    QMessageBox.warning(self,'错误','生成图片文件为空')
                    self.event(exit())
            else:
                QMessageBox.warning(self,'错误','文件为空,请稍后')
        else:
            QMessageBox.warning(self, '错误', '文件为空,请稍后')

最后设置一个程序的启动主函数 –name-- ==–main– ;

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

最后


以上就是基于 pyqt5 开发这个简单 图片编辑器的 整个过程;程序中存在的不足当然还有很多,界面也没有进行任何的美化,因为自己也刚接触这个库,也在学习阶段当中;

相关文章
|
6月前
|
计算机视觉 C++
基于Qt的简易图片浏览器设计与实现
基于Qt的简易图片浏览器设计与实现
291 1
|
JavaScript 对象存储
在阿里云OpenAPI 为什么oss 图片链接, 在浏览器访问直接下载了,不是预览呢?
在阿里云OpenAPI 为什么oss 图片链接, 在浏览器访问直接下载了,不是预览呢?
1340 1
|
3月前
|
XML 缓存 JSON
为什么浏览器中有些图片、PDF等文件点击后有些是预览,有些是下载
为什么浏览器中有些图片、PDF等文件点击后有些是预览,有些是下载
251 0
|
5月前
|
Web App开发 JavaScript 前端开发
使用 JS 实现在浏览器控制台打印图片 console.image()
在前端开发过程中,调试的时候,我们会使用 console.log 等方式查看数据。但对于图片来说,仅靠展示的数据与结构,是无法想象出图片最终呈现的样子的。 虽然我们可以把图片数据通过 img 标签展示到页面上,或将图片下载下来进行预览。但这样的调试过程实在是复杂,何不实现一个 console.image() 呢?
123 1
使用 JS 实现在浏览器控制台打印图片 console.image()
|
4月前
|
Web App开发 前端开发
canvas保存图片时,谷歌浏览器Chrome报错【解决方案】Not allowed to navigate top frame to data URL
canvas保存图片时,谷歌浏览器Chrome报错【解决方案】Not allowed to navigate top frame to data URL
133 0
|
5月前
|
缓存 算法 API
视觉智能开放平台产品使用合集之如何在Web浏览器中查看处理后的图片
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
160 0
|
6月前
|
域名解析 应用服务中间件 对象存储
解决阿里云oss图片浏览器访问直接下载而不是打开
解决阿里云oss图片浏览器访问直接下载而不是打开
3430 0
|
6月前
|
移动开发 JavaScript
微信公众号H5开发,在微信浏览器打开H5,无法一键下载图片
微信公众号H5开发,在微信浏览器打开H5,无法一键下载图片
213 0
|
JavaScript
Qt图片浏览器
可以显示jpg、jpeg、png、bmp。可以从电脑上拖动图到窗口并显示出来或者打开文件选择 重载实现dragEnterEvent(拖拽)、dropEvent(拖拽放下)、resizeEvent(窗口大小改变)
109 0
|
Swift iOS开发
iOS PhotoBrowser 横竖屏图片浏览器
iOS PhotoBrowser 横竖屏图片浏览器
157 0