Data management for simple calculation tool
-
Hello,
I have build an application for some simple calculations and I'm struggling with the management of the data (which is here the input and output data as shown in the picure)
So far the app is working but I'm unhappy about the data handling:
By now every input-field is connected to a slot where the calcaulation is done after all the data is read in from all the ui-fields. I'm using the textEdited slot so that the calculation is done every time when a value gets changed.What I have in mind is that I have different data-classes (each has only one object which will be send to other classes by reference) for every calculation tab which store the input values as well as the results. Whenever an input value is changed it should be changed in the data-class of the corresponding calculation.
This way should enable me to read the input values as well as the results and print them later on in a report (this will be the next step of development).
Here is an example how one of my data-classes looks like:
class DataFlexuralAspectRatio { public: DataFlexuralAspectRatio(); void setHeight(double height); double getHeight(); private: double height{25}; double d1{0}; double d2{0}; double asreq{0}; double asreqComp{0}; double fck{0}; double span{0}; int comboSystemCoeff{0}; int comboNA{0}; };The implementation file of mainwindow looks like:
#include "mainwindow.h" #include "ui_mainwindow.h" #include "model/DataStorage/DataFlexuralAspectRatio.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //Creating the data objects DataFlexuralAspectRatio DataFlexuralAspectRatioObj; //Inserting the Widgets for the tabs ReinforcementsView* reinforcementsview = new ReinforcementsView; ui->gridLayoutReinforcements->addWidget(reinforcementsview); EarthPressureView* earthpressureview = new EarthPressureView; ui->horizontalLayoutEarthPressure->addWidget(earthpressureview); FlexuralAspectRatioView* flexuralaspecratioview = new FlexuralAspectRatioView(this, DataFlexuralAspectRatioObj); ui->verticalLayoutFlexuralAspectRatio->addWidget(flexuralaspecratioview); //add close application connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close); } MainWindow::~MainWindow() { delete ui; }From my understanding I concluded that I have to connect the signal textEdited of each input field to two different slots. The first slot saves/updates the value in the corresponding data-class and the second slot starts the calculation. The latter is then using the input-values directly from the data-class instead of gettimg them from the ui.
Do you guys think this is a good way of handling the data or do you have a better approach?
-
Hi,
The cleanest would be to have your widgets expose an API with signals and slots that you will connect to your controller class. That way you keep the controller and the GUI cleanly separated.
-
I'm unfortunately not much experienced in programming and pretty new to c++..
What do you mean by API? Do you mean some sort of controller to work as a layer between the view and my data- and calculations classes?
-
API stands for Application Programming Interface. If you read a class documentation, you will have its API description there and how to use it.
As for your question, create a class that will do all the "controlling".
Since you are starting, read on encapsulation, model-view-controller and these kind of patterns. That will help you a lot. As already suggested, single responsibility is also good.
Also, do drawings of the interactions in your application it will allow you to have clearer ideas of how it should work.
-
Thanks for your brainstorming SGaist!
I think I'm starting to get an idea how it should be like.
I builded a minimal example for adding two numbers (A and B) with the following classes:
MainWindow <-> ControllerClass <-> DataClass
CalculationViewIn the constructor of MainWindow I instantiate CalculationView and ControllerClass. ControllerClass get's the pointer of CalculationView passed. The DataClass is implemented as singleton.
So the aim would be to manage all the interactions between CalculationView and DataStorage with the ControllerClass.
As ui is a private member of CalculationView I can't access it within the controller. So I think I have to write custom methods and signals in CalculationView (keyword API!?) to interact with the GUI from other classes. For example I build a method for reading the content of a lineEdit:
QString CalculationView::getA() { return ui->lineEditA->text(); }Right now im still stuck how to access the buildin signals of CalculationView (here: textEdited) from the controller. I don't understand how to make the custom signal.
Am I on the right path? Do you have a hint for me how to make this signal?
-
getA looks correct.
For the signal part, read this chapter of Qt's documentation about signals and slots.
Note that you can connect your line edit signal to your custom signal (provided that the signatures matches), it's called signal forwarding.
-
Thanks a lot. After having build my minimal example with the mvc-pattern I implemented it the same way in my application and it helped so much to organise my application and beeing able to know what is done where.
The forwarding is done by simply connecting a signal to a signal. This is what I wrote in the constructor of the ViewClass:
//forwarding the signals from private ui to custom signals connect(ui->lineEditA, &QLineEdit::textEdited, this, &CalculationView::lineEditAChanged_signal); connect(ui->lineEditB, &QLineEdit::textEdited, this, &CalculationView::lineEditBChanged_signal);In the header file I added:
signals: void lineEditAChanged_signal(); void lineEditBChanged_signal();