Speed Up Your GUI Development with Python Qt and QML Live Coding

Live Coding Workflow 4 minutes read

Are you still hitting the Run button every time you want to verify a GUI element in your Python Qt and QML application looks as you expected?

Or are you relying on your working memory to imagine the changes in your mind?

Both approaches work, but you are wasting a lot of time and energy, which you could spend more productive on coding.

In this article, you will learn about an approach called live coding which I frequently use during GUI development with Qt QML.

The idea is to shorten feedback loops by automatically reloading the GUI whenever you change the source code.

Additionally, we combine the automatic reloading with prototype or playground UIs, where you can work on parts of the UI in an isolated manner.

I see live coding as the GUI counterpart to test-driven development for normal source code. It’s all about more consistent development speed thanks to shorter feedback loops. In fact, TDD and live-coding are a great combination when working with Python Qt and QML.

Live coding for QML applications is nothing I have invented. There is also the now official QmlLive Bench. However, so far it only supports Qt/C++ applications.

Moreover, I noticed that for bigger projects you need to write your own live coding environment anyway. For example, I also added live coding to QtQuickVcp as demonstrated in this video.

Components

The live coding environment is fairly simple. In fact, it’s so simple that you can easily implement it for each of your projects. It consists of following software components:

  • FileWatcher: Watches your file system for changes and sends out notification signals.
  • ModuleLoader: Searches a directory tree for Python QML modules to load.
  • PythonReloader: Restarts the whole application to re-register alls Python QML modules.
  • ProjectBrowser: Lists all QML files in a directory tree.
  • QML Loader: This is the Loader component provided by Qt. It enables users to load and reload QML code at run-time.

With these few simple components, we can easily build our own small live coding environment. Additionally, we may have some code handle errors attached to sys.excepthook plus a small GUI.

How does it work

The concept is as simple as it is powerful.

Instead of loading our GUI application as normal, we inject the QML part of our live coding environment between the top level window and our GUI code.

Live Coding QML applications
Live Coding QML applications

For production, we can use our GUI code as usual, for development we use the live coding environment.

Sometimes we have resources or loading-time expensive components. For example a 3D simulation window. We can place these components outside of our live coding environment to speed up loading time.

Structuring the Code

When working with Python and QML we have GUI code written int the QML language and business logic written in Python.

Our business logic code is loaded into the GUI as QML component as part of QML module. A QML module is the equivalent of a Python module, but for QML.

A QML module may contain both, QML code and Python code. Therefore, it makes sense to let the Python and QML code live together in a single directory.

For example, a QML module providing logic and GUI representation of a file system browser may look as follows:

- [filesystem]
  - qmldir
  - __init__.py
  - file_system_tree_model.py
  - FileSystemTreeView.qml

The qmldir file registers the QML components into QML module. The __init__.py file does the same for the Python QML components.

To discover Python QML module, the __init__.py contains a register_qml_types method.

# -*- coding: utf-8 -*-
from PyQt5.QtQml import qmlRegisterType

from .file_system_tree_model import FileSystemTreeModel

MODULE_NAME = 'filesystem'


def register_types():
    qmlRegisterType(FileSystemTreeModel, MODULE_NAME, 1, 0, FileSystemTreeModel.__name__)

This makes it easy for our ModuleLoader to automatically find and register any QML Python modules.

The Python Qt Live Coding Environment

To make our life as HMI engineers easier, I created a Python Qt live coding environment that comes with all the required parts to start hacking on a Python QML GUI.

You can find the project on GitHub: python-qt-live-coding

Python Qt Live Coding Environemnt
Python Qt Live Coding Environemnt

You can install it via pip:

pip install python-qt-live-coding

The live coding environment comes with a live runner which enables your to live
code Qt GUIs quickly.

Run following to test drive the example:

python_qt_live_coding examples

You will instantly see the example project in the live runner.

Live Runner Example
Live Runner Example

Now you can either select the MainScreen.qml file or type MainScreen in the filter.

When you type, the file will be automatically selected.

When loaded you will see following.

Live Coding Example 2
Live Coding Example 2

This is the example GUI inside the live runner.

Now press the Edit button. Your favorite text editor should open promptly.

Edit the code inside the editor and you will see the GUI updates instantly when you save the document.

Conclusion

Live coding is a great concept that can be applied to Python Qt and QML applications.

The python-qt-live-coding project brings you everything you need in a box.

Additionally, it can be used a base for a custom live-coding environment for your application.

Happy coding!

Your Machine Koder

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.