This repo is a tutorial set for understanding using QML with Python for creating GUIs. Python was chosen due to its status as a modern lingua franca of coding, but the concepts apply to over a dozen languages. In fact, the QML files allows changing the backend implementation language without making any changes to the interface.
Through a series of alternating sections, we’ll create a small data analysis application. We will attempt to alternate making changes to the python and the QML to help emphasise the separation.
The hello folder contains a minimal example of QML code. Any QML code that does not require work from the Python backend can be loaded from this Python example.
Run the example
python3 main.py
- Change the background to a less garish colour.
- Give a more personal greeting.
The stats folder starts the journey of interacting between QML and Python. The module will load a file of X and Y values and display the means of the columns.
- model.py
- A class for providing statistics to QML.
- Create new properties to display the sums of the columns
The display folder provides a better display for the statistics that we calculated in the last chapter. We also introduce the two different types of layout in QML: managed and anchored
- Put the X and Y means on the same row
- Move the title to the bottom of the window
- Move the title to the left side of the window
- Remove the
GridLayout
and layout the entire window with anchors (this will be tedious).
The filename folder modifies the Stats
class to allow the file name to be
chosen by the QML file. This introduces both setters for properties
and the concept of a Signal
. Thus far, our getters have always been
calculations on the data. We want the calculation to be performed
again when the data is updated, but we don’t want to waste resources
by continuously performing the same calculation repeatedly. This
dilemma is solved by attaching a notification signal to the property.
The QML only calls into python to update the data when it receives the
appropriate signal. In turn, we can emit this signal at any point in
our python code where we feel this update is needed.
- Set title text to the name of the data file
The ineractive folder adds the first truly interactive elements to our QML file.
A button can be clicked to display a file dialog, which will then
update the data file in our Stats
model. The onClicked
and
onAccepted
properties are examples of binding to the clicked
and
accepted
properties, respectively.
- Using the
console.log
function, bind to thedataChanged
signal on theStats
model and print the file name to the console every time the data changes. - Find a better position for the file dialog button.
- Create a
bool
property on theStats
model that explains whether a file has been loaded.
The table folder is a major change compared to the previous updates.
The Stats
model is updated to inherit from QAbstractTableModel
instead of merely QObject
. This tells Qt that our model contains
tabular data and requires that we add three new methods to our code.
- rowCount
- The number of rows in our table
- columnCount
- The number of columns in our table
- data
- The value at a specific index in the table
Each of these functions takes the Slot
decorator. A slot is a
function that can be called from QML.
The QML was also update to put the stats on the right side of the
window and a table of the data on the left hand side. The TableView
requires a delegate
parameter, which is a QML element that will be
draw for each data item
- The current code will produce glitches if the data file has more than two columns. Either ignore the other columns (easy) or allow an arbitrary column number.
The chart folder holds an alternate view of our data. Instead of the stats and tables of our previous examples, it contains a 2D plot of the data. While this is a nice example of the Qt Charts library, the critical lesson of this example is that this change occurs without editing a single line of Python code. It is a sign of high code quality when a model is used in multiple QML files or when a single QML file is applied to multiple models, as this indicates a strong decoupling between the model and the display. This is not always achievable at the highest level, but should be a goal for smaller components.
- The current chart range is hard coded. Add the necessary data
properties to the
Stats
model to allow the axes to scale with the data.