Opinion on architecture - pieces of data emitting and receiving signals
-
Pretty new to Qt, so I was questioning the architecture of my app and wanted an opinion.
When entering a certain mode (we'll call it display mode), my app displays the choices (made by the user in a different mode) for a set of variables and allows the user to modify certain choices. Technically speaking, the display mode runs on three big object:
- A singleton that stores all the available choices for every variable - this is common to many mode of the app
- An object (we'll call it a Sheet) that stores the choices made by the user for every variable
- A QWidget responsible for what is actually displayed. It holds a pointer to a Sheet object (as the user can load and unload the Sheet it wants to be displayed) and pointers to all view widgets needed. Those view widgets get the scope of available choices directly from the singleton.
The difficult part is that the view widgets displayed are customizable, so the user can choose twice the same view widget. This made me think it would be a good idea to decouple Sheet and view widgets using the signal/slot mechanism by making the Sheet object emit and receive signals for the variables it holds.
Implementing this proved very time consuming and not much flexible: having just 10 variables means 10 hardcoded signal and slots on the Sheet object. So I decided to dip down the idea one level, by making everything in Sheet a QObject able to emit and receive signals. So now I have something like this:class Sheet { public: Sheet(); SignalingString * getChoiceForVariable1() const; SignalingInt * getChoiceForVariable2() const; SignalingInt * getChoiceForVariable3() const; private: SignalingString * choiceForVariable1; SignalingInt * choiceForVariable2; SignalingInt * choiceForVariable3; };
Where SignalingString and SignalingInt are QObject wrappers for the respective types which emit signals when the value it holds is modified. View widgets connects directly to the proper SignalingString/SignalingInt to keep coherency between themeselves and with the Sheet.
This can create some problems given the restrictions on QObjects (no copy constructor for example) and was wondering if there is a better way to structure it, keeping also in mind that in future the number and type of variables will be dynamically determined at runtime.
-
From the looks of it, you are trying to hardcode things that are pretty dynamic in nature.
You should completely decouple the choices, the selection of the choices and the GUI. These are different concepts.
So you may something like:
- A model that offers the "variables" and their possible values (AKA choices)
- A model that will store whatever the user has selected (looks like you Sheet object but refactored to be a model)
- A widget that will allow your user to make these selection and store them in a Sheet
- Another widget that will show the content of that Sheet like for example QTableView on top of a custom QAbstractTableModel
In fact, it almost look like a database with custom views on top.
-
Hi,
Sounds like Qt's model view programming could be worth a read.
-
From the looks of it, you are trying to hardcode things that are pretty dynamic in nature.
You should completely decouple the choices, the selection of the choices and the GUI. These are different concepts.
So you may something like:
- A model that offers the "variables" and their possible values (AKA choices)
- A model that will store whatever the user has selected (looks like you Sheet object but refactored to be a model)
- A widget that will allow your user to make these selection and store them in a Sheet
- Another widget that will show the content of that Sheet like for example QTableView on top of a custom QAbstractTableModel
In fact, it almost look like a database with custom views on top.