Skip to main content

A lightweight and powerful WebView2 widget for Python Qt (PySide/PyQt) with a seamless JS bridge.

Project description

QtWebView2

PyPI version License Python versions Downloads

| English | 简体中文 |

📖 Introduction

QtWebView2 is a Python wrapper for embedding Microsoft's WebView2 into a Qt application, complete with a powerful JS bridge. It is built upon QtPy and Python.NET.

Disclaimer: This project is currently in a beta stage. The API may change in future updates, but early adopters and feedback are welcome!

✨ Features

  • 🎸 Lightweight Integration: Directly wraps the native WebView2 control using Python.NET, resulting in a minimal increase in your application's package size compared to solutions like QWebEngineView.
  • 🎻 Powerful JS Bridge: Provides a robust JS bridge solution for seamless two-way communication between Python and JavaScript, using modern JS features like Promise and async/await.
  • 🎷 Thread-Safe: Most API calls are carefully designed to be thread-safe, ensuring stability and safety in multi-threaded environments by leveraging Qt's signal and slot mechanism.
  • 🎺 Out-of-the-Box: Comes with rich configuration options and robust error handling, allowing you to get started quickly with minimal setup.
  • 🎼 QtPy Support: Built on QtPy, making it compatible with both PyQt6 and PySide6.

⬇️ Installation

⚠️ Note: This library currently supports the Windows platform only.

python -m pip install qtwebview2

Alternatively, you can install from the source:

git clone https://github.com/xiaosuyyds/QtWebView2.git
cd QtWebView2
python -m pip install .

Important! The corresponding Qt backend is not installed as a dependency. You need to install your preferred backend (e.g., PySide6 or PyQt6) yourself.

🧑‍💻 Usage

Here is a complete example demonstrating the core features.

import sys
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
from qtpy.QtCore import Slot, QCoreApplication
from qtwebview2 import QtWebView2Widget, DictJsBridge

# Set an application name for the user data folder
QCoreApplication.setApplicationName("QtWebView2-Demo")

# 1. Initialize the application and window
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle("QtWebView2 - JS Bridge Demo")
window.setGeometry(100, 100, 800, 600)
layout = QVBoxLayout(window)

# 2. Create an instance of the JS bridge
js_bridge = DictJsBridge()

# 3. Create the WebView2 widget and inject the JS bridge
webview = QtWebView2Widget(parent=window, js_apis=js_bridge)
layout.addWidget(webview)


# 4. (JS -> Python) Define a Python function and expose it to JavaScript
@js_bridge.bind_js_api_func
def get_user_os():
    """This Python function will be callable from JavaScript."""
    print(f"Python function 'get_user_os' was called from JavaScript!")
    return sys.platform


# 5. Define HTML content that includes JavaScript to call the Python function
html_content = """
<!DOCTYPE html>
<html>
<head><title>JS Bridge Test</title></head>
<body style="font-family: sans-serif; text-align: center; background-color: #f0f0f0;">
    <h1>QtWebView2 JS Bridge Demo</h1>
    <button onclick="callPython()">Click me to call Python!</button>
    <p>Result from Python: <b id="result">...</b></p>
    <script>
        async function callPython() {
            try {
                // Use async/await to call the Python function and get the result
                const os = await window.qtwebview2.api.get_user_os();
                document.getElementById('result').textContent = os;
            } catch (e) {
                document.getElementById('result').textContent = 'Error: ' + e;
            }
        }
    </script>
</body>
</html>
"""

webview.load_html(html_content)


# 6. (Python -> JS) Connect to a signal and execute JavaScript when it's emitted
@Slot()
def on_dom_loaded():
    """This function is called when the web page's DOM is fully loaded."""
    print(f"DOM content loaded. Executing JS from Python...")
    # You can also execute JavaScript from Python
    webview.evaluate_js("""(function() {
        const new_element = document.createElement('h2');
        new_element.textContent = 'Hello from Python!';
        document.body.appendChild(new_element);
    })()""")


webview.bridge.domContentLoaded.connect(on_dom_loaded)

window.show()
sys.exit(app.exec())

License

Copyright (c) 2025 Xiaosu.

Distributed under the terms of the Mozilla Public License Version 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qtwebview2-0.1.1.tar.gz (382.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qtwebview2-0.1.1-py3-none-any.whl (380.7 kB view details)

Uploaded Python 3

File details

Details for the file qtwebview2-0.1.1.tar.gz.

File metadata

  • Download URL: qtwebview2-0.1.1.tar.gz
  • Upload date:
  • Size: 382.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qtwebview2-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9118ecd12ecc05dcc87c08d1f09812fa1ba528a550b8587b57c72cc5ab68dca9
MD5 85c05e3dd7e000771f21b9bcebfe95b6
BLAKE2b-256 0e9a37c75c69e955d2b4270b5103e0c84e625e5b1c7884ddee9f1fa52cd8e6fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for qtwebview2-0.1.1.tar.gz:

Publisher: publish-to-pypi.yml on xiaosuyyds/QtWebView2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qtwebview2-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: qtwebview2-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 380.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qtwebview2-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f9bb8599355c6602be219ec96bda049eaecddc757bae1964c03a50a6f1124819
MD5 033dd472280336f38fddef8f0aafe8cd
BLAKE2b-256 c236b81b5c58f6273cbfec5156da7c8006df9932f268a0bb3d733f0c8e05d0de

See more details on using hashes here.

Provenance

The following attestation bundles were made for qtwebview2-0.1.1-py3-none-any.whl:

Publisher: publish-to-pypi.yml on xiaosuyyds/QtWebView2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page