您现在的位置是:首页 > 技术教程 正文

pywebview桌面程序开发(技术路线:前端+Python,全网独一份!!!!!!)

admin 阅读: 2024-03-29
后台-插件-广告管理-内容页头部广告(手机)

一、pywebview

官网:https://pywebview.flowrl.com/

1、简介

pywebview声称Build GUI for your Python program with JavaScript, HTML, and CSS。就是可以使用web技术来实现桌面应用程序开发。其内核我理解仍然是浏览器,只不过将浏览器封装成系统窗口,这样就可以将web无缝切换到桌面应用,相比pyQt等重武器还是比较方便的。

对于目前比较火的electron,Python的加入给应用程序提供了上限,据说打包的大小也比electron小。

2、安装

pip install pywebview
  • 1

Hello world 的demo:

import webview webview.create_window('Hello world', 'https://pywebview.flowrl.com/') webview.start()
  • 1
  • 2
  • 3

3、依赖

windows程序依赖pythonnet(要求 > .NET 4.0),pythonnet可以让python调用.NET代码。

为了使用最新版本的 Chromium(Chromium是谷歌的开源项目,国产的所有 “双核浏览器”,都是基于 Chromium 开发的,甚至 Chrome 也是基于它。),需要安装WebView2。

选择Web应用还是原生应用来开发是一种在通用性和本地权限之前的权衡。WebApp兼容的范围很广,而且Web前端代码基于浏览器天生跨平台,而且前端框架多好开发。而原生应用有很大本地权限,可以进行各种文件和操作系统接口的调用。WebView可以结合这两者的优点进行开发。WebView2允许你在本地App里面嵌入web相关的技术(例如HTML,CSS和JavaScript)。WebView2控件使用微软的Edge作为渲染引擎,你可以嵌入一部分或者整个App都用WebView来做。

WebView2下载地址:https://developer.microsoft.com/en-us/microsoft-edge/webview2/?form=MA13LH

4、使用

4.1、最简单示例

import webview window = webview.create_window('Woah dude!', 'https://pywebview.flowrl.com') webview.start()
  • 1
  • 2
  • 3
  • 4
  • create_window:

    返回窗口实例,该实例可以使用许多窗口操作和DOM函数,可创建任意数量窗口,在GUI循环启动后创建的窗口会立即显示。所有打开的窗口都以列表形式存储在webview.windows中。create_window第二个参数可以是url(远程url或本地url),也可设置html来加载html。html与url同时存在,html优先级高。

4.2、http server示例

pywebview提供一个与WSGI兼容的http服务器。

import webview webview.create_window('Woah dude!', 'index.html') webview.start(http_server=True)
  • 1
  • 2
  • 3
  • 4

将http_server设为true

一般使用外部WSGI兼容的http服务器,将服务器对象作为url传递

from flask import Flask import webview server = Flask(__name__, static_folder='./assets', template_folder='./templates') webview.create_window('Flask example', server) webview.start()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.3、线程模型

webview.start会开启一个GUI循环,并且它是一个阻塞函数。当GUI循环被阻塞时,必须在一个单独的线程和进程中执行后端逻辑

。可以通过手动开启线程/进程,或者将函数作为要启动的第一个参数来启动。第二个参数设置函数的参数。这种方法会在后台启动一个线程,与手动起一个线程相同。

import webview def custom_logic(window): window.evaluate_js('alert("welcome")') window = webview.create_window('Woah dude!', html='

Woah dude!

') webview.start(custom_logic, window) # anything below this line will be executed after program is finished executing print(2)#只有窗口关闭了才能打印
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

4.4、Python与evaluate_js通信

  • 在Python调用Javascript

    使用evaluate_js可以在Python中调用Javascript 函数,如:window.evaluate_js(‘alert(“welcome”)’)

  • 在Javascript 中调用Python

    方法1(十分反人类):在一个Python类中先写一个html网页,在其中的Javascript 使用pywebview.api.方法名来调用Python函数,方法名不能以下划线开头。示例如下:

    import random import sys import threading import time import webview html = """

    JS API Example

    pywebview is not ready






    """
    class Api: def __init__(self): self.cancel_heavy_stuff_flag = False def init(self): response = {'message': 'Hello from Python {0}'.format(sys.version)} return response def getRandomNumber(self): response = { 'message': 'Here is a random number courtesy of randint: {0}'.format( random.randint(0, 100000000) ) } return response def doHeavyStuff(self): time.sleep(0.1) # sleep to prevent from the ui thread from freezing for a moment now = time.time() self.cancel_heavy_stuff_flag = False for i in range(0, 1000000): _ = i * random.randint(0, 1000) if self.cancel_heavy_stuff_flag: response = {'message': 'Operation cancelled'} break else: then = time.time() response = { 'message': 'Operation took {0:.1f} seconds on the thread {1}'.format( (then - now), threading.current_thread() ) } return response def cancelHeavyStuff(self): time.sleep(0.1) self.cancel_heavy_stuff_flag = True def sayHelloTo(self, name): response = {'message': 'Hello {0}!'.format(name)} return response def error(self): raise Exception('This is a Python exception') if __name__ == '__main__': api = Api() window = webview.create_window('JS API example', html=html, js_api=api) webview.start()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151

    方法二:将Python函数公开到Javascript域,示例如下:

    import webview def lol(): print('LOL') def wtf(): print('WTF') def echo(arg1, arg2, arg3): print(arg1) print(arg2) print(arg3) def expose(window): window.expose(echo) # expose a function during the runtime window.evaluate_js('pywebview.api.lol()') window.evaluate_js('pywebview.api.wtf()') window.evaluate_js('pywebview.api.echo(1, 2, 3)') if __name__ == '__main__': window = webview.create_window( 'JS Expose Example', html='

    JS Expost' ) window.expose(lol, wtf) # expose functions beforehand webview.start(expose, window, debug=True)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    方法三(最实用)

    运行一个PythonWeb服务,让前端代码对其API进行调用。对于将Web一直到应用程序非常便捷。

4.5、事件

Windows对象有许多声明周期事件,订阅事件使用+=语法,即windows.events.loaded+=函数名,事件触发时会调用该函数,不能重复订阅,多次订阅也只调用一次。取消订阅使用windows.events.loaded-=函数名。

  • events.closed:窗口关闭后触发的事件
  • events.closing:窗口正在关闭,在确认时候触发的事件
  • events.loaded:DOM准备就绪时触发的事件
  • events.minimized:窗口最小化触发的事件
  • events.restore:窗口恢复时触发的事件
  • events.maximized:窗口最大化触发的事件
  • events.resized:窗口大小变化时触发的事件
  • events.shown:窗口显示时触发的事件

5、常用示例

5.1、10秒后改变加载的url

import time import webview def change_url(window): # wait a few seconds before changing url: time.sleep(10) # change url: window.load_url('https://pywebview.flowrl.com/hello') if __name__ == '__main__': window = webview.create_window('URL Change Example', 'http://www.google.com') webview.start(change_url, window)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

5.2、带有确认对话框的窗口

import webview def open_confirmation_dialog(window): result = window.create_confirmation_dialog('Question', 'Are you ok with this?') if result: print('User clicked OK') else: print('User clicked Cancel') if __name__ == '__main__': window = webview.create_window( 'Confirmation dialog example', 'https://pywebview.flowrl.com/hello' ) webview.start(open_confirmation_dialog, window)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

5.3、常用事件

import webview def on_closed(): print('pywebview window is closed') def on_closing(): print('pywebview window is closing') def on_shown(): print('pywebview window shown') def on_minimized(): print('pywebview window minimized') def on_restored(): print('pywebview window restored') def on_maximized(): print('pywebview window maximized') def on_resized(width, height): print( 'pywebview window is resized. new dimensions are {width} x {height}'.format( width=width, height=height ) ) def on_loaded(): print('DOM is ready') # unsubscribe event listener webview.windows[0].events.loaded -= on_loaded webview.windows[0].load_url('https://pywebview.flowrl.com/hello') def on_moved(x, y): print('pywebview window is moved. new coordinates are x: {x}, y: {y}'.format(x=x, y=y)) if __name__ == '__main__': window = webview.create_window( 'Simple browser', 'https://pywebview.flowrl.com/', confirm_close=True ) window.events.closed += on_closed window.events.closing += on_closing window.events.shown += on_shown window.events.loaded += on_loaded window.events.minimized += on_minimized window.events.maximized += on_maximized window.events.restored += on_restored window.events.resized += on_resized window.events.moved += on_moved webview.start(debug=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

5.4、文件打开

import webview def open_file_dialog(window): file_types = ('Image Files (*.bmp;*.jpg;*.gif)', 'All files (*.*)') result = window.create_file_dialog( webview.OPEN_DIALOG, allow_multiple=True, file_types=file_types ) print(result)#result为文件的绝对路径 if __name__ == '__main__': window = webview.create_window('Open file dialog example', 'https://pywebview.flowrl.com/hello') webview.start(open_file_dialog, window)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5.5、文件保存

import webview def save_file_dialog(window): import time time.sleep(5) result = window.create_file_dialog( webview.SAVE_DIALOG, directory='/', save_filename='test.file' ) print(result) if __name__ == '__main__': window = webview.create_window('Save file dialog', 'https://pywebview.flowrl.com/hello') webview.start(save_file_dialog, window)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜