| English | 简体中文 |
wryview is in early development. The API may change without notice between versions. It was created to serve QtWebView, a Qt webview widget project, and the author is a Rust beginner — the binding code may not be idiomatic. Feedback, bug reports, and contributions (code or ideas) are very welcome.
wryview is a Python binding for wry, the cross-platform WebView rendering library used by Tauri. It wraps the full wry API — no event loop, no window management, just the webview.
Built on PyO3 and distributed as pre-compiled wheels (no Rust toolchain required for end users).
- Zero Event Loop — wryview creates the webview as a child of your window. Your GUI framework owns the event loop. No conflicts, no deadlocks.
- Full wry API — Navigation, JavaScript execution, IPC (
window.ipc.postMessage), custom protocols, cookies, drag & drop, proxy, devtools, zoom, and more. - Cross-Platform — Windows (WebView2), macOS (WKWebView), Linux (WebKitGTK). Same API everywhere.
- Framework-Agnostic — Embed into Qt, tkinter, wxPython, or any native window via HWND/NSView/XID.
- Pre-Built Wheels —
pip install wryviewjust works. No Rust, no cmake, no system deps (beyond the OS webview).
pip install wryviewWindows: WebView2 Runtime is required (pre-installed on Windows 10 1803+, or download).
macOS: WKWebView is built-in.
Linux: Requires libwebkit2gtk-4.1-dev and related packages (see wry docs).
from wryview import WebView
# Embed as a child of any native window (default)
wv = WebView(parent_hwnd, url="https://example.com", devtools=True)
# Fill an independent window — wry manages size via WM_SIZE / layout
wv = WebView(anchor_hwnd, url="https://example.com", as_child=False)
# JS execution
wv.eval_js("document.body.style.background = '#333'")
# JS → Python IPC (JS side: window.ipc.postMessage('hello'))
wv.set_ipc_handler(lambda msg: print(f"JS says: {msg}"))
# Navigation callback
wv.set_on_page_load(lambda event, url: print(f"{event}: {url}"))
# Custom protocol (intercept requests asynchronously)
def my_handler(method, uri, headers, body, respond):
# respond(status, headers, body) must be called from any thread
respond(200, {"Content-Type": "text/html"}, b"<h1>Hello from Python!</h1>")
wv = WebView(hwnd, custom_protocols={"myapp": my_handler}, url="myapp://localhost/")| Category | Methods |
|---|---|
| Content | load_url, load_html, load_url_with_headers, reload, url |
| JavaScript | eval_js, eval_js_with_callback |
| IPC | set_ipc_handler, clear_ipc_handler |
| Callbacks | set_on_navigation, set_on_page_load, set_on_title_changed, set_on_new_window, set_drag_drop_handler |
| Geometry | set_bounds, bounds |
| Appearance | set_visible, set_background_color, focus |
| DevTools | open_devtools, close_devtools, is_devtools_open |
| Cookies | cookies, cookies_for_url, set_cookie, delete_cookie |
| Other | zoom, print, clear_all_browsing_data |
Full constructor options: transparent, background_color, incognito, user_agent, autoplay, initialization_script, proxy, back_forward_gestures, clipboard, and more.
- QtWebView — A cross-platform webview widget for Qt (PySide/PyQt), powered by wryview. Embeds a wry WebView as a native child window inside any Qt widget, with a seamless JS bridge and WSGI support.
The author is a Rust beginner — if you see something that could be improved, please open an issue or PR. All contributions (code, ideas, documentation) are welcome.
Copyright (c) 2026 Xiaosu.
Distributed under the terms of the Mozilla Public License Version 2.0.