pywebview

repository·master·Indexed 27 days ago

https://github.com/r0x0r/pywebview

A lightweight native webview wrapper that allows developers to build GUI for Python programs using JavaScript, HTML, and CSS. It provides Python-to-JavaScript communication, DOM support, a built-in HTTP server, and the ability to display HTML content in native GUI windows across multiple platforms.

Tokens
13.5K
Snippets
37
Records
104
Agent score
85%

What's inside pywebview

  1. Overview of pywebview features

    master

    pywebview is a lightweight native webview wrapper that displays HTML content in a native GUI window.

    Key Features:

    • Native GUI Backends: Uses WinForms on Windows, Cocoa on macOS, and QT or GTK on Linux.
    • Two-way Communication: Enables interaction between JavaScript and Python.
    • Built-in HTTP Server: Includes a server to serve local content.
    • DOM Support: Provides DOM support directly in Python.
    • Window Management: Includes window manipulation, an event system, application menus, and native dialogs.
    • Small Footprint: Does not bundle heavy GUI toolkits or web renderers when frozen, keeping executable sizes small.
  2. Get started with pywebview basics

    master

    To launch a basic window, use webview.create_window to define the window title and the URL (or HTML content) to load, then call webview.start() to begin the GUI loop.

    Windows created before webview.start() appear when the loop starts. Windows created after the loop starts appear immediately. You can manage multiple windows via webview.windows (a list of windows in creation order) and access the currently focused window using webview.active_window().

    import webview
    
    window = webview.create_window('Woah dude!', 'https://pywebview.flowrl.com')
    webview.start()
  3. Create a Hello World window

    master

    To create a basic native window that displays a web URL, use webview.create_window() to define the window properties and webview.start() to launch the application loop.

    import webview
    webview.create_window('Hello world', 'https://pywebview.flowrl.com/')
    webview.start()
  4. Communicate between JavaScript and Python

    master

    Python to JavaScript

    Use window.evaluate_js(code) to run JS from Python. To handle asynchronous JS (Promises), provide a callback: window.evaluate_js(code, callback).

    JavaScript to Python

    To expose Python methods to the JavaScript window object, pass an instance of a class to the js_api parameter in webview.create_window(url, js_api=api_instance).

    Methods of the class will be accessible in JavaScript via window.pywebview.api.methodName(). You can also use window.expose(func) to expose individual functions during runtime.

    import webview
    
    class Api():
      def log(self, value):
        print(value)
    
    webview.create_window("Test", html="<button onclick='pywebview.api.log(\"Woah dude!\")'>Click me</button>", js_api=Api())
    webview.start()
  5. Expose Python functions to Javascript

    master

    There are two primary ways to make Python code callable from the Javascript domain via the pywebview.api object.

    1. Using the js_api parameter in create_window

    Pass an instance of a Python class to the js_api argument when creating a window.

    • Mapping: All callable methods of the class are exposed as pywebview.api.method_name.
    • Naming Rules: Method names must not start with an underscore. Attributes or methods starting with _ are hidden.
    • Nesting: Nested classes are converted to nested objects in Javascript. However, nested classes with the attribute _serializable = False will be omitted.

    2. Using window.expose(func)

    You can expose specific functions at runtime by calling window.expose(your_function).

    • Mapping: Functions are exposed as pywebview.api.func_name.
    • Precedence: If a name clash occurs between the js_api and functions added via expose, the expose functions take precedence.

    Important Implementation Details

    • Promises: All exposed functions return a Javascript Promise. If the Python function raises an exception, the promise is rejected with a Javascript Error (access the stacktrace via error.stack).
    • Threading: Exposed functions run in separate threads and are not thread-safe.
    • Availability: pywebview.api might not be ready immediately on window.onload. Always subscribe to the window.pywebviewready event before attempting to call the API.
  6. Subscribe to Window events

    master

    To subscribe to lifecycle or management events on a window object, use the += syntax. To unsubscribe, use the -= syntax. Duplicate subscriptions are automatically ignored.

    When writing an event handler, the first positional argument must be the window object itself.

    Note on threading: Most window events are asynchronous and execute in separate threads. However, before_show, before_load, and initialized are synchronous and will block the main thread until the handler completes.

  7. Use the JS API bridge with a built-in HTTP server

    master

    You can use the JS API bridge to enable communication between Python and JavaScript without an external web server. To serve static content, set the entrypoint URL to a local relative path; pywebview will automatically start a built-in HTTP server.

    To create the bridge, use webview.create_window(..., js_api=Api()) or the window.expose function.

  8. Create a drag region in frameless windows

    master

    In a frameless window, you can make specific HTML elements act as handles to move or drag the window by adding the CSS class pywebview-drag-region to them.

    You can customize this behavior by re-assigning the webview.settings['DRAG_REGION_SELECTOR'] property in Python.

    <div class='pywebview-drag-region'>Now window can be moved by dragging this DIV.</div>
  9. Configure pywebview dependencies on macOS

    master

    For macOS, you may need pyobjc. While it is preinstalled with the Python bundled in macOS, standalone Python installations require it. You do not need the full package; the following specific packages are sufficient:

    • pyobjc-core
    • pyobjc-framework-Cocoa
    • pyobjc-framework-Quartz
    • pyobjc-framework-WebKit
    • pyobjc-framework-security

    You can also use QT on macOS.