What the Heck is Qt Quick’s Model View Architecture
By: Brad
Hey Brad I’m new to Qt Quick and I’ve read something about a Model/View architecture what the heck is that?
The Model/View architecture of Qt is actually used by both Qt Widgets and Qt Quick, its one and the same, and is a way to separate the UI logic from the business logic. It also allows for loose property binding which asynchronously updates the UI whenever the data in the model is updated.
In Qt (which from this point on will refer to both Qt Widgets and Qt Quick) they have a concept of a Model much like the model in the MVC pattern which exposes the data to the view (the data could be coming from an API or storage) and contains all the business logic your app needs to do whatever it was design to do. They also have a concept of a View again much the same as the MVC pattern which is where you describe how to present the data to the end user and is where we capture user input. In fact the Model View (MV) of Qt is exactly like the Model and View in the MVC pattern minus the need for a Controller.
Qt did add one more word to our vocabulary and that word is Delegate. What is a Delegate? A Delegate well its also a view, a visual representation of data. What is the difference between a View and a Delegate?
Nothing really they are both “Views”, i.e. visual representation of data, its just that one (View) is a visual representation of a collection of data and the other (Delegate) is a visual representation of a piece of data. For example lets say you have a Model which represents an array of numbers 0 through 9. My View would be the visual representation of the entire collection, that is how do I show the concept of a collection to a user; do I lay it out vertically, horizontal, as a grid or in a table. The Delegate would visually represent the objects within the collection (i.e. the numbers); that is how do I draw a number on screen, what font do I use, what colour, is it bold or underlined, are there any graphics.
In the above the Delegate describes that the data (i.e. the numbers) are to be presented on screen as a string using Calibri 60pt font, bolded and using the colour white. The string should be encased within a blue rounded cornered rectangle. The View states that the data should be layed out in a grid with two rows and 5 columns and defines the spacing between the rows and columns.
Coming from WPF I found the use of the word Delegate confusing as I was use to calling them sub-views; however I feel that the decision to use the word Delegate was the Qt teams way of trying to not over saturate the word “View”.
Something to watch out for when it comes to using the terms View and Model in Qt is if you look at Qt documentation when they say the word View they don’t really mean the same thing as the View in MVC or MVVM (WPF), they have limited the scope to just the representation of a collection of data vs. the representation of the entire application.
In WPF anything you see on the screen is a View; the main application GUI is in fact the View however that View is probably made up of a number of sub-views which are reusable components or the application might allow you to tab through a number of different screens where each screen in WPF would also be referred to as a View.
(Excuse the poorly done UI its just a quick mock to illustrate what I’m meaning here).
Each button is a reusable View defined by the framework, the ribbon control along the top is similarly in its own right a View. Along the left hand side there is a button strip, pressing one button will replace the center space with a new screen; that screen is a custom View we would have had to create specifically for this application where each screen or View would be defined in their own XAML file. As you can see the main View is a mosaic of sub-Views but they are all the same: A View is the physical description of how to present data, commands and user input controls to the end user.
In Qt they went a different rout with the term View; it really means exactly the same thing as defined in MVC or MVVM but they focus it on the layout of a collection of data.
In Qt they have a number of Views such as QListView, QTableView, QTreeView for Qt Widgets or ListView, TableView, GridView, etc. for Qt Quick. It is these things that Qt is referring to when they say the term View. In WPF we would have called them Layouts.
Why is the term View only refering to these View classes? It’s because the model is viewed as simply a collection of data; the fact that the model may also have its own properties outside of that collection (like a selection counter) or a number of commands (exposed via the Q_INVOKABLE macro) that manipulate the data in the collection which also need visual representations does not seem to be generally talked about or at least considered to be part of the MV pattern on the Qt forms.
So if we take the same MOCK UI and look at it from Qt’s point of view only the list of buttons along the left would be considered a View (assuming all other UI elements are manually placed on the screen without using one of the View classes).
Coming from WPF where a Model is more then just a collection of data and a View describes all aspects of a Model, and I really don’t see a reason why we should limit the scope to only the collection assuming the model even has one, I tend to use the MVVM definitions which can lead to some confusion when talking to people who are using the Qt MV definitions. To me I can’t help but ask if the Model and View are only for the collection of data then who owns or what do we call all the other aspects of the Model and View (i.e. commands (Q_INVOKABLE), properties (Q_PROPERTY), other visual elements outside of a View class)?
I don’t know if this was Qt’s intention but it’s what I’ve observed, maybe it was just because they used the term View in the naming of these layout classes. For me I use the MVC/MVVM definition of the term View and use it to refer to the entire UI or sometimes for the sake of compatibility with Qt I refer to the UI as the application/UI View and the ListView/TableView/GridView as the Collection’s View.
With that all said I can expand the above UML drawing that represented how Views, Models and the Data relate to now take into account for Delegates.
The internal view shown in the diagram is the Collection’s View (i.e. a ListView or TableView), the Visual Elements are other things on the main UI which is not part of the ListView/TableView/GridView/etc. The internal Model is the Collection’s Model and the Properties are Q_PROPERTY properties external of the collection of data which expose other pieces of data to the View (i.e. a count of how many items in the collection have been selected).
So that is what the heck the Qt’s Model View Architecture is, an architectural pattern that separates an application into two parts. One part represents the information/data the application will contain and another part which describes how to represent that information to the user.
Commercial break...
Curve Ball
Before I finish on this topic I want to throw an idea by you. In another post What the Heck is MVVM I presented a design patter similar to MVC but introduced a second Model called a View Model. The idea is that the Model is the same as in MVC, that is it just holds data and business logic, but the View Model is an adapter that wraps the Model in a way to allow the data to be exposed to the View. This way we keep the Model free of any UI required artifacts (i.e. the model may use get and set methods but the view might require properties, instead of injecting properties into the model (which you might not own) you wrap the get/set methods in properties within your View Model). When I look at Qt’s MV architectural pattern I see exactly the same thing.
What the Qt MV architectural pattern calls a Model I would call a View Model and what they call Data I would call a Model (or Data Model for clarity). I could create my model which holds all the data and business logic without using Q_PROPERTY’s or never emit the dataChanged() signal, it might not even use the Qt Framework which leaves it agnostic and able to be wrapped in a Command Line application, a WPF application or even exposed as a JSON API without the burden of all the gruff needed by Qt Quick to connect it to the View; all of the View required hooks would be in my View Model that only my Qt Quick application would use.
So that’s it, that was all I wanted to share; you can use the Qt MV pattern as Qt describes it where you co-locate the UI required hooks and business logic into one class, which is fine if your Model will only ever be used by your Qt Quick application or you can apply the MVVM pattern (its not just for WPF) and give your self a model that can be used in multiple applications if so needed. It’s up to you and your situation, I just wanted to share that insight.
If you have any questions or comments feel free to leave them below and I’ll respond when time permits.
Until next time think imaginatively and design creatively