前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PySimpleGUI 进阶| 原来用Python做一个图片查看系统,还能这么简单!

PySimpleGUI 进阶| 原来用Python做一个图片查看系统,还能这么简单!

作者头像
刘早起
发布2020-12-07 10:16:20
2.6K0
发布2020-12-07 10:16:20
举报
文章被收录于专栏:早起Python早起Python
系列导读

PySimpleGUI|基础讲解

大家好,在昨天的文章中我们已经介绍了为什么以及如何基本使用PySimpleGUI,并且对一些比较常用的元素(element)也有所了解。

本文将对基础版中的一些元素与新讲解的元素进行组合,构建一个图片查看系统与一个简易的计算机视觉系统(代码调用前置照相机)

作为PySimpleGUI的进阶篇,我将分为以下两个部分讲解:

  • 图片查看系统的构建
  • 简易计算机视觉系统(cv)的构建

本次内容主要涉及的Python模块:

  • PySimpleGUI
  • os
  • cv2

图片查看系统的构建

1、代码与效果呈现

开门见山,先看最终效果和代码,后面再解读,在本节我们需要实现的就是如下图所示的一个图片查看系统,左边输入图片所在文件夹,就可以按顺序查看图片

下面为全部的源码,可以看到并不是很多,这也体现了我们之前说的简单性

代码语言:javascript
复制
import PySimpleGUI as sg
import os.path
file_list_column = [
    [
        sg.Text("Image Folder"),
        sg.In(size=(25, 1), enable_events=True, key="-FOLDER-"),
        sg.FolderBrowse('浏览'),
    ],
    [
        sg.Listbox(
            values=[], enable_events=True, size=(40, 20), key="-FILE LIST-"
        )
    ],
]
image_viewer_column = [
    [sg.Text("从左边图片列表中选择一张图片:")],
    [sg.Text(size=(40, 1), key="-TOUT-")],
    [sg.Image(key="-IMAGE-")],
]
layout = [
    [
        sg.Column(file_list_column),
        sg.VSeperator(),
        sg.Column(image_viewer_column),
    ]
]
window = sg.Window("图片查看系统", layout)
while True:
    event, values = window.read()
    if event == "Exit" or event == sg.WIN_CLOSED:
        break
    if event == "-FOLDER-":
        folder = values["-FOLDER-"]
        try:
            file_list = os.listdir(folder)
        except:
            file_list = []

        fnames = [
            f
            for f in file_list
            if os.path.isfile(os.path.join(folder, f))
            and f.lower().endswith((".png", ".gif"))
        ]
        window["-FILE LIST-"].update(fnames)
    elif event == "-FILE LIST-":  
        try:
            filename = os.path.join(
                values["-FOLDER-"], values["-FILE LIST-"][0]
            )
            window["-TOUT-"].update(filename)
            window["-IMAGE-"].update(filename=filename)

        except:
            pass

window.close()
2、代码解读

首先先温故一下上篇基础章节的内容,默认端口下的PySimpleGUI只对PNG、GIF等格式,而常见的JPG、TIFF格式是不能被其调用的。如果想调用的话可以用Python中的另一个库Pillow来转换。

按照我们的构造GUI基本框架:

引入模块

\Longrightarrow

创建元素并填充layout

\Longrightarrow

创建窗体

\Longrightarrow

创建事件循环

代码语言:javascript
复制
import PySimpleGUI as sg
import os.path
file_list_column = [
    [
        sg.Text("Image Folder"),
        sg.In(size=(25, 1), enable_events=True, key="-FOLDER-"),
        sg.FolderBrowse('浏览'),
    ],
    [
        sg.Listbox(
            values=[], enable_events=True, size=(40, 20), key="-FILE LIST-"
        )
    ],
]

上述代码layout中的第一个列表元素,是如下图的代码

代码中引入os模块对文件夹进行调用,在创建一个垂直方向的元素嵌套列表file_list_column,里面的元素如上图般放置。在嵌套列表里有4个元素:

  • Text
  • InputText
  • FolderBrowse
  • Listbox

其中代码中的In等价于InputText,在上节中有提及。总体来说,上述元素的功能就是打开图片所在文件夹和陈列所有图片信息。

Text中写的"Image Folder"是一个标识,用来说明。 InputText中先设置了框的大小是长25,宽1的单位长度。 enable_eventskey两个参数是一起用的。这里的参数key是GUI中非常重要的参数,是用来在整个GUI中鉴别特殊的元素的。比如此处中,定义了一个"-FOLDER-"的身份给- InputText这个元素。有了这个key,你可以在循环事件中去调用它。学习过其他GUI库,诸如wxpythonTkinter等,这个key就像是用来绑定事件的函数一样。在面向对象语言中,这就像定义了一个类一般。但这些都是非常复杂的,而做的像key这样的,足可以说明PySimpleGUI的便利。单独来讲,key是用来标记的,enable_events就是用来控制元素对应事件循环中开始与结束,相当于执行元素中的事件。 最后一个元素是Listbox,显而易见,这是用来展示所选文件列表中的所有照片路径的信息。你可以在这个列表中点击你想看的照片。对于这个列表箱子,你可以传递字符串列表来填充他。 Listbox是一个列表箱子,顾名思义是一个列表类型的。 在Listbox里面先设置了空的列表值,这是因为第一次打开图形交互页面时,由于你没有选择文件夹,所以对应的箱子是空的。和上面一样设置的keyenable_events标记了key为"-FILE LIST-"与开启绑定事件功能,并且设置了(40,20)的大小。 ”

接下里看layout中的第二个列表元素

代码语言:javascript
复制
image_viewer_column = [
    [sg.Text("从左边图片列表中选择一张图片:")],
    [sg.Text(size=(40, 1), key="-TOUT-")],
    [sg.Image(key="-IMAGE-")],
]

这是如图的代码:

这里有三个元素:两个TextImage

“第一个Text元素是说明让使用者在左边列表中选择一个想看的照片. 第二个Text是显示已选择的图片基本信息,同时给予了key-TOUT-,大小为(40,1)。 第三个元素就是上节介绍的Image元素,给予了key-IMAGE-的身份标识。可以看到这里没用到enable_events,因为像图片这种,我们只需观看它,而不需要由它生成事件。 ”

下一步就是合并到layout中

代码语言:javascript
复制
layout = [
    [
        sg.Column(file_list_column),
        sg.VSeperator(),
        sg.Column(image_viewer_column),
    ]
]

上面代码便是将两个的布局列表以一列一列的形式合并在一起,注意,这里出现了一个新的函数VSeperator()VSeperator()VerticalSeparator()的简写,仔细观察的读者可以留意到整个GUI中的中间有一条黑色的直线.

没错,这个代码的功能就是这条黑线。这条黑线是用来分割两个列表布局的,你可以设置一些参数来决定每个布局的比例。

下面就是创建窗体

代码语言:javascript
复制
window = sg.Window("图片查看系统", layout)

最后便是创建一个事件循环,这里分逻辑讲解

代码语言:javascript
复制
while True:
    event, values = window.read()
    if event == "Exit" or event == sg.WIN_CLOSED:
        break

在整个事件中,除了获取事件与对应的值外,你可以通过调用key来与相应的元素进行对话,这样取出来的值就是你选择得key与其对应得值字典。

这里用了条件语句来执行什么事件发生,什么事件不发生。

第一个逻辑条件语句如下

代码语言:javascript
复制
    if event == "-FOLDER-":
        folder = values["-FOLDER-"]
        try:
            # Get list of files in folder
            file_list = os.listdir(folder)
        except:
            file_list = []

        fnames = [
            f
            for f in file_list
            if os.path.isfile(os.path.join(folder, f))
            and f.lower().endswith((".png", ".gif"))
        ]
        window["-FILE LIST-"].update(fnames)

如果事件等于-FOLDER-,即你点击了key = -FOLDER-对应的元素,那么接下来就会进行选择文件夹的步骤,这里使用了os.listdir()来得到文件列表,然后将选择的文件列表里的图片加上".png",或".gif"后缀。同时运用.update()函数在列表箱子Listbox里更新所选列表中的所有图片信息。

第二个逻辑代码如下

代码语言:javascript
复制
    elif event == "-FILE LIST-":  # A file was chosen from the listbox
        try:
            filename = os.path.join(
                values["-FOLDER-"], values["-FILE LIST-"][0]
            )
            window["-TOUT-"].update(filename)
            window["-IMAGE-"].update(filename=filename)

        except:
            pass

如果事件等于-FILE LIST-,那么相当于使用者在左边的列表箱子中选择了一个图片文件。选择之后,同样运用.update()函数更行ImageText元素中的信息。

在两个逻辑中都是用关键字key来调用相应的元素事件:window[key]

最后就是关闭程序

代码语言:javascript
复制
window.close()

有读者会问,直接按GUI中的离开按钮不香吗? 答案是可以的,但作为程序员,代码是你与计算机交互的工具。

还有一个原因就是在web端的GUI中,如果直接按离开按钮,虽然页面是关闭了,但是这个网页面还是会占据你内存

简易的计算机视觉系统搭建

作为彩蛋,我们最后讲解一个基于PySimpleGUI简易计算机视觉系统搭建

计算机视觉(Computer Vision)是指用计算机实现人的视觉功能——对客观世界的三维场景的感知、识别和理解。而这次的简易计算机视觉系统,将诠释感知与识别。和上节一样,先上代码

代码语言:javascript
复制
import tkinter
import cv2, PySimpleGUI as sg
USE_CAMERA = 0      
window, cap = sg.Window('简易的计算机视觉系统', [[sg.Image(filename='', key='image')], ], location=(0, 0), grab_anywhere=True), cv2.VideoCapture(USE_CAMERA)
while window(timeout=20)[0] != sg.WIN_CLOSED:
    window['image'](data=cv2.imencode('.png', cap.read()[1])[1].tobytes())

通过上面简单的代码,就能调用电脑摄像头了!小编长得没郭富城帅,这里就不做效果呈现了.......

需要注意的是,你需要将你笔记本的摄像头权限打开,不然会报错!!!下面简单讲解一下上面的代码:

PySimpleGUI部分的构建在构建图片查看系统中有提及,这里就不细讲。主要是创建一个只有Image元素的窗体,运行一个逻辑:只有没按关闭按钮就一直循环的事件。这里新增了一个新函数grab_anywhere=True,是用来启用非阻塞窗口的。

主要讲解一下涉及到的cv2的一些用法:

cv2.VideoCapture(0):打开笔记本的内置摄像头,参数为0。如果参数是视频文件路径,则打开视频 cv2.imencode():这个函数将图片格式转换(编码)成流数据,赋值到内存缓存中;主要用于图像数据格式的压缩,方便网络传输。随之相应的就是 cv2.imdecode():指从指定的内存缓存中读取数据,并把数据转换(解码)成图像格式;主要用于从网络传输数据中恢复出图像 ”

以上便是本次pySimpleGUI进阶版内容讲解,当然我们只是基于图片查看系统的讲解,掌握了方法之后,感兴趣的读者可以自己开发Excel/Word等文档查看系统

本文的分享就到这里,在下一篇的实战讲解内容中,我们将结合爬虫,更详细的讲解如何做一个带有GUI的爬虫程序

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 早起Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、代码与效果呈现
  • 2、代码解读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档