Converting Flask into a Desktop App
By: Andrew Udell
Tags: Flask, Python, Web Development

Converting Flask into a Desktop App

Photo by Carl Heyerdahl on Unsplash

From web development to data science, Python offers an incredibly diverse set of tools. Its easy-to-read syntax and quick learning curve makes it a popular language but it lacks the diverse and beautiful GUI support of web technologies. Anyone who’s used Flask, a popular and lightweight web framework, has probably wondered if they could take the same principles and apply them to desktop app development. The temptation of combining an HTML and CSS frontend with a Python backend is alluring,

A few libraries attempt to achieve this, but lack the customization options and don’t have a large community. Instead, the web engine module in the immensely popular Qt GUI library offers the same effect.

Qt for Python

As a toolset for creating cross-platform GUI’s with free and open-source licensing options, the Python bindings for Qt are quite popular among developers. While an entire tutorial could be written about all the modules and features of Qt, its web engine in particular can create an Electron-style app.

Built on top of a snapshot of Chromium, the Qt WebEngine is a fully developed browser capable of rendering HTML, CSS, and JavaScript. It’s easy to use and only requires a few lines to start using with local HTML files.

Here’s the basic set up:

from PyQt5.QtCore import *

from PyQt5.QtWebEngineWidgets import *

from PyQt5.QtWidgets import QApplication

import sys qt_app = QApplication(sys.argv) # Initialize web engine

web = QWebEngineView() # Set window title

web.setWindowTitle("Window Name")



# set window size

web.resize(900, 800) # set window zoom

web.setZoomFactor(1.5) # load the url

web.load(QUrl("file.html")) # Show the results

web.show()

sys.exit(qt_app.exec_())

After a few imports, the web engine is initialized and parameters, such as the window title, size, and zoom are set. With the local HTML file (or website) specified, a new window will appear with its contents. No address or toolbar block the view, so as far as end-users are concerned, it’s not a browser.

This alone offers great potential to develop offline web apps, but it necessarily sacrifices any meaningful connection to a backend. Luckily, this can be fixed with Flask.

Integrating the Qt WebEngine with Flask

By using Flask to create a local server, Python can handle all the underlying logic. While creating a full local server is unusual for creating a desktop app, it offers the best and most succinct approach to converting Flask applications.

Here’s how to set it up:

from flask import Flask

from PyQt5.QtCore import *

from PyQt5.QtWebEngineWidgets import *

from PyQt5.QtWidgets import QApplication

from threading import Timer

import sys # Start using all the regular flask logic

flask_app = Flask(__name__)

.route("/")

def hello():

return "Hello World" # Write to main page @flask_app .route("/")def hello():return "Hello World" # Define function for QtWebEngine

def ui(location):

qt_app = QApplication(sys.argv) web = QWebEngineView()

web.setWindowTitle("Window Name")

web.resize(900, 800)

web.setZoomFactor(1.5)

web.load(QUrl(location))

web.show()



if __name__ == "__main__":

# start sub-thread to open the browser.

Timer(1,lambda: ui("

flask_app.run(debug = False) sys.exit(qt_app.exec_())if __name__ == "__main__":# start sub-thread to open the browser.Timer(1,lambda: ui(" http://127.0.0.1:5000/ ")).start()flask_app.run(debug = False)

None of the typical Flask logic or structure is changed. The addition of a function to handle the Qt WebEngine is added and then placed into a sub-thread on a timer to execute after the Flask app starts. Since both processes are essentially infinite loops, trying to run them sequentially simply won’t work.

Conclusions

By using the power of Qt, beautiful CSS frameworks augmented by JavaScript can be brought to offline desktop apps powered by Flask. Requiring less than 15 lines of code, it concisely broadens the capabilities of web-based technologies while even further diversifying Python’s possible applications.