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

2024-05-13 1414阅读

一、pywebview

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

pywebview桌面程序开发(技术路线:前端+Python,全网独一份!!!!!!)
(图片来源网络,侵删)

1、简介

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

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

2、安装

pip install pywebview

Hello world 的demo:

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

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()
  • 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)
    

    将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()
    

    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)#只有窗口关闭了才能打印

    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 = """
      
      
      
      
      
          #response-container {
              display: none;
              padding: 3rem;
              margin: 3rem 5rem;
              font-size: 120%;
              border: 5px dashed #ccc;
          }
          label {
              margin-left: 0.3rem;
              margin-right: 0.3rem;
          }
          button {
              font-size: 100%;
              padding: 0.5rem;
              margin: 0.3rem;
              text-transform: uppercase;
          }
      
      
      
      

      JS API Example

      pywebview is not ready

      Hello Python
      Perform a heavy operation
      Get a random number
      Say hello to: Greet
      Catch Exception
      window.addEventListener('pywebviewready', function() { var container = document.getElementById('pywebview-status') container.innerHTML = 'pywebview is ready' }) function showResponse(response) { var container = document.getElementById('response-container') container.innerText = response.message container.style.display = 'block' } function initialize() { pywebview.api.init().then(showResponse) } function doHeavyStuff() { var btn = document.getElementById('heavy-stuff-btn') pywebview.api.doHeavyStuff().then(function(response) { showResponse(response) btn.onclick = doHeavyStuff btn.innerText = 'Perform a heavy operation' }) showResponse({message: 'Working...'}) btn.innerText = 'Cancel the heavy operation' btn.onclick = cancelHeavyStuff } function cancelHeavyStuff() { pywebview.api.cancelHeavyStuff() } function getRandomNumber() { pywebview.api.getRandomNumber().then(showResponse) } function greet() { var name_input = document.getElementById('name_input').value; pywebview.api.sayHelloTo(name_input).then(showResponse) } function catchException() { pywebview.api.error().catch(showResponse) } """ 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()

      方法二:将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)

      方法三(最实用):

      运行一个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)
        

        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)
        

        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)
        

        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)
        

        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)
        
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]