吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5937|回复: 10
收起左侧

[Python 转载] 简单轻量的GUI编程--PyWebview

[复制链接]
thepoy 发表于 2020-11-13 13:58
本帖最后由 thepoy 于 2020-11-22 21:45 编辑

有新项目了,正在写,见下面更新
主流的GUI以windows平台为主,其次是macOS, 最后才轮得到linux,正好,pywebview在linux上写代码并不舒服,所以可以说这个库/包是windows和macOS专用的,或者说更适合在这两个平台上开发。
正如其名,这是一个以HTML展示,web项目在后端处理基本的软件逻辑的GUI库,比PyQT轻量得多得多。

web建议后端用restful-api(flask、fastapi等轻量框架)实现,前端用ajax传递数据。

本次分享以windows为例。
在windows上,PyWebview是以edge内核开发的,如果想调试,需要在微软应用商店安装edge开发调试软件--Microsoft Edge DevTools。
先上样图(很像一个浏览器):
4293de98d5c4fcf63df6615630a1ac6.png


11-13  17.29更新

项目结构如下:

├── backend   # 后端处理
│   ├── __init__.py
│   ├── main  # 功能函数
│   └── web   # web函数
├── manage.py  # 看名字就知道这是什么了
├── static   # 前端静态文件
├── templates   # 前端HTML模板

pywebview官方文档只能看api,不能看示例,示例不算是一个合格的项目。

一个PyWebview项目最关键的就是manage.py文件,我写的项目的内容如下:

import logging
import webview

from io import StringIO
from contextlib import redirect_stdout

from backend.web import create_flask_app

logger = logging.getLogger(__name__)

if __name__ == '__main__':
    stream = StringIO()
    with redirect_stdout(stream):
        window = webview.create_window(
            "图片批处理工具 1.0.0",
            create_flask_app(),
            width=920,
            resizable=False,
            text_select=False,
            background_color="#000"
        )

        webview.start(debug=True)

manage.py是整个项目的调用文件,这个文件中的关键代码是:

window = webview.create_window(
                "图片批处理工具 1.0.0",
                create_flask_app(),
                width=920,
                resizable=False,
                text_select=False,
                background_color="#000"
)

webview.start(debug=True)

api文档:
创建一个新的 pywebview 窗口。首次调用此函数时将启动应用程序并占用程序主线程。您必须在单独的线程中执行您的程序逻辑。后续调用 create_window 将返回一个唯一窗口 uid,该窗口可用于引用 API 函数中的特定窗口。单窗口应用程序无需理会 uid,在函数调用中可以直接忽略它。

  • title - 窗口标题
  • url - 要加载的 URL。如果 URL 没有协议前缀,则将其解析为相对于应用程序入口点的路径。
  • js_api - 将 js_api 类对象公开给当前 pywebview 窗口的 DOM 。JavaScript 可以通过 window.pywebview.api 对象来对 js_api 进行函数调用。回调函数可以接受一个参数的基本类型或对象。对象类型在 JavaScript 和 Python 间转换。函数在单独的非安全的线程中执行。
  • width - 窗口宽度。默认值为 800px。
  • height - 窗口高度。默认值为 600px。
  • resizable - 窗口大小是否可以调整。默认为 True。
  • fullscreen - 窗口全屏模式, 默认值为 False。
  • frameless - 窗口无边框模式,默认值为 False。
  • min_size - 窗口最小尺寸,元组类型 (width, height), 默认值为 (200x100)。
  • strings - 窗口本地化语言配置,字符串的字典类型。默认值在 localization.py 中定义。
  • confirm_quit - 窗口退出时是否显示确认对话框,默认值为False。
  • background_color - 窗口的 WebView 在 loaded 之前的背景颜色。指定为十六进制颜色。默认为 white。
  • debug - 启用调试模式,默认值为 False。
  • text_select - 启用 WebView 的文档文本选择,默认值为 False。如需单独指定元素的文本选择,可以使用 CSS 的 user-select 属性。

manage.py文件需要一个最基本的web项目作为连接前端和后端的过度/中间人,我用的是flask,我的flask项目结构为:

web
├── __init__.py
├── settings.py  # flask配置文件
└── views
    ├── __init__.py
    └── first.py  # 如果视图函数复杂的话,可能需要分成若干个文件

每个人可能都有自己的flask项目结构,所以这方面就不再赘述了。

现在有了web了,接下来就是主角出场了——真正的后端功能函数,我给它起的名字是main,其结构为:

main
├── exceptions.py
├── filename_handler.py  # 处理文件名
├── __init__.py
├── spider_handler.py  # 处理爬虫
└── XXX_handler.py  # 处理XXX

其实叫handlers或controllers可能更合适,只是叫main更能凸显它的重要性。

这里的函数就看自己怎么写了,这是整个项目的中心功能所在。

spider_handler.py为例,只是一个简单地爬取一个网页内所有图片的爬虫,其内容为:

class Spider:
    def __init__(self, url: str, output: str, cookie: str = ''):
        self.url: str = url
        self.output: str = output
        self.headers: dict = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
        }
        if cookie:
            self.header['Cookie'] = cookie

    def __parse_image_urls(self, html: str) -> List[str]:
        soup = BeautifulSoup(html, 'lxml')
        img_tags = soup.find_all('img')
        return [urljoin(self.url, img_tag['src']) for img_tag in img_tags]

    def __save_all_image_file(self) -> int:
        html = self.__get_html_response()
        if html:
            srcs = self.__parse_image_urls(html)
            count = 0
            for src in srcs:
                img_response = requests.get(src, headers=self.headers)
                if img_response.status_code == 200:
                    img_file = img_response.content
                    with open(f"{self.output}/spider_img_{ts}{suffix}", 'wb') as f:
                        f.write(img_file)
                        count += 1
                    except UnidentifiedImageError:
                        continue
            return count

    def __get_html_response(self) -> str:
        response = requests.get(self.url, headers=self.headers)
        if response.status_code == 200:
            return response.text
        else:
            return ''

    def get_all_images(self) -> dict:
        try:
            count = self.__save_all_image_file()
            return {"status": 'ok', 'count': count}
        except Exception as e:
            return {'status': 'error', 'error': str(e)}

作为一个handler函数,一定要有返回值,方便在flask视图函数里调用并直接返回结果。

视图函数里的相关内容为:

from flask import Blueprint, jsonify, request
from backend.main.spider_handler import Spider

first = Blueprint("first_bp", __name__)

@first.route("/spider", methods=['POST'])
def spider_images_from_url():
    data = request.json

    url = data['url']
    output = data['output']

    spider = Spider(url, output)
    response = spider.get_all_images()
    return jsonify(response)

如第一张图的内容所见,当传递完url和output后,spider就开始运行了,这里有兴趣的人可以在前端展示进度,需要配合js完成。

11-18  10:09更新

正在写一个小项目,PC微信文件清理工具,进度有些慢,因为正在熟悉FastAPI,这个项目也是用来练习FastAPI的练手之作。

https://github.com/thep0y/WFCleanUpTool

11-18 18:05更新

Linux上的完成度示意图:
1605693858.png

11-22 18:18更新

大概能返回文件夹的大小了
微信截图_20201122182019.png

11-22 21:43更新

已完成初步的文件删除功能,会尽快打包发布。
微信截图_20201122214527.png

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
细水流长 发表于 2020-11-13 14:18
提示: 作者被禁止或删除 内容自动屏蔽
Zeaf 发表于 2020-11-13 14:20
麦米尔加弗德 发表于 2020-11-13 15:02
看起来还可以,最近我也在找gui,楼主有什么推荐的教程吗?
741956 发表于 2020-11-13 15:40
下载地址呢? 先拿出来看看啊
Cool_Breeze 发表于 2020-11-13 15:45
看看,等更新
 楼主| thepoy 发表于 2020-11-13 18:20
细水流长 发表于 2020-11-13 14:18
不懂,楼主有例子吗,我和pyqt对比下

我只有一个完整的项目,不知道你要怎么对比。
 楼主| thepoy 发表于 2020-11-13 18:21
麦米尔加弗德 发表于 2020-11-13 15:02
看起来还可以,最近我也在找gui,楼主有什么推荐的教程吗?

没有教程,看官方文档
zhorses 发表于 2020-11-15 14:48
python 的gui 是个恶性循环啊。。。
xu程序员 发表于 2020-11-15 15:29
挺好的一个思路啊。
万物都可以往python上转。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-23 07:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表