Open Dash app in PySide6 QWebEngineView browser

Hi All,

Is there a way to open my dash app in a PySide6 QWebEngineView browser?

PySide6 QWebEngineView browser is a barebones browser window built using PySide6 and wish to display my dash app in this browser instead of my system browser. This way my Dash app can be like a desktop app, and I hope that closing the browser window would terminate the program execution properly.

The goal is that the python script launches the PySide6 browser and loads the Dash app in it without any copy-paste of localhost:8050 link., and close when I close the browser window.

Is there a way to do this?

Below, I have pasted the code I have been working on. I know there is a problem with the if_name_main section, where I call the browser and app.run, but couldn’t figure out how to make it work.

Your help is greatly appreciated.

Thank you :smiley:

import sys
import dash
from dash import html
import dash_bootstrap_components as dbc

from PySide6.QtCore import QUrl
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWidgets import QApplication, QMainWindow

# Code to create simple browser modified to work with PySide6
# Source: https://www.pythonguis.com/examples/python-web-browser/
class MainWindow(QMainWindow):
    def __init__(self, _url):
        super().__init__()
        self.url = _url

        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl(self.url))

        self.setCentralWidget(self.browser)


def launch_browser(url):
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    window = MainWindow(url)
    window.show()
    sys.exit(app.exec())


# Dash application begins
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = dbc.Container([
    dbc.Row([dbc.Col(html.H1("Test Dashboard", className="py-3"))]),
])

# Set default port
port = 8050
browser_url = f"http://localhost:{port}/"

if __name__ == "__main__":
    launch_browser(browser_url)
    app.run(debug=True, port=port)

How about launching dash app in a new thread before setting up QApplication, eg:

import threading

def run_dash():
    app = Dash(__name__)
    app.layout = ...
    app.run(port=...)

thread = threading.Thread(target = run_dash, daemon = True).start()

@echeung Thank you for pointing me in the right direction. Threading does the trick but one needs to add an additional argument to run the app. use_reloader=False in app.run(debug=True, use_reloader=False, port=port).

The complete code is shown below. The sources are cited appropriately.

Thank you once again.

import sys
import dash
import threading
from dash import html
import dash_bootstrap_components as dbc

from PySide6.QtCore import QUrl
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWidgets import QApplication, QMainWindow


# Code to create simple browser modified to work with PySide6
# Source: https://www.pythonguis.com/examples/python-web-browser/
class MainWindow(QMainWindow):
    def __init__(self, _url):
        super().__init__()
        self.url = _url

        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl(self.url))

        self.setCentralWidget(self.browser)


def launch_browser(url):
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    window = MainWindow(url)
    window.show()
    sys.exit(app.exec())


# Set default port
port = 8050
browser_url = f"http://localhost:{port}/"

# https://github.com/plotly/dash-core-components/issues/952#issuecomment-2015163046
# https://stackoverflow.com/questions/77724451/how-to-run-a-dash-app-with-threading-and-with-debug-true
def run_dash():
    app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
    app.layout = dbc.Container([
        dbc.Row([dbc.Col(html.H1("Test Dashboard", className="py-3"))]),
    ])  
    app.run(debug=True, use_reloader=False, port=port, dev_tools_ui=False)

if __name__ == "__main__":
    thread = threading.Thread(target=run_dash, daemon=True).start()
    launch_browser(browser_url)