How to divide program - Qt, C++ using mvc logic - c++

At the beginning I want to tell that I just started learning QT so my knowledge about this is really not deep. I wrote simple tasks management it's a console application of course. I used logic which resembles MVC pattern (controllers, views, actions, models).
For example let's take user login. I create instance of LoginController class, then LoginController creates instance of LoginView who is waiting for user to enter data - login, password. Login and password is saved as LoginView members. Then in LoginController I read this data and passes them as parameters to UserVerificationAction constructor. Constructor of this class saved this data as members of their class. Next in LoginController I calls method of class UserVerification - action() which validates login and password. Then depending on the result of validation I create instance of MenuController or instance of LoginFailiedView. This mechanism is user throughout the program (CreateUserController, AddTaskController) etc. I used virtual methods so MenuController consists of about 20 lines of code and is very easy to read.
I want to use Qt to implement a GUI to be more precise I want to use signals and slots mechanism but I have a dilemma. Maybe it would by better to create a slot in the LoginView class and then creates action instance instead passes entered data to LoginView members and then in LoginController creates instance od action class. maybe there is a better way to do this. I want you to give me some tips on how I should do it properly
p.s.
Sorry for my English

In Qt, the concept of a "controller" is slightly blurred. It tends to be part of both the model and view. This does not mean that you can't write a controller to link a model and view logic.
Normally what you will see is a view that emits signals for its actions. And then you wire these either directly into compatible slots on a model or a subclass where you have written your own slots.
If for instance you have a main window. This window might create a model and a view as children. And it may then define slots on the window subclass that wire between the model and view. This means your window is a view and a controller.

Qt provides Model/View architecture.
It introduces 3 classes: Model, View and Delegate to store, present and edit data.
I believe that is what you are looking for.

Related

Qt / CPP: how to implement callbacks with signals and slots the "right way"

I'm trying to implement an application in Qt with a model-view-controller scheme. I have some model classes (databases), one application controller, and a bunch of GUI classes. All GUI classes know the app controller and can call its public slots to send data to it that should be stored in the model. The app controller takes the data and calls the appropriate database to store it. The database classes check the data and return a bool to the app controller to tell if the data was okay or not.
Now, one GUI element has prepared some user data and wants to send it to the app controller. I am trying to figure out how to let the GUI-class know that the app controller validated the incoming data with the model and it accepted the data. My app controller shouldn't care nor know which GUI elements call its public API to commit data to the model. But how does the app controller communicate a response to the GUI element to tell it, that everything was fine, so the GUI element can close itself?
My idea would have been to let the GUI element create a random number token to send it to the app controller together with the data as a kind of "callback address". As soon as my GUI element receives an okay signal with the correct token attached, it can react to that.
I was dunno. All my solutions feel weird and not how it's supposed to be in Qt.
Edit 1: a pseudo-code example for clarification:
void Appcontroller::Slot(userdata)
{
bool okay = database->save(userdata)
};
void Appcontroller::CreateMasterWindow()
{
this->masterwindow_ = new MasterWindow(this);
// I am propagating the knowledge of the app controller to the
// MasterWindow and the latter can propagate that info further
// down, that's fine (everybody can know the responsible
// controller, but I don't think the controller should care about
// all his bastard children)
};
void MasterWindow::CreateSubWindow()
{
this->subwindow_ = new SubWindow(appcontroller_);
// the masterwindow creates a random subwindow that the controller
// should't have to care about
};
void SubWindow::SendUserData(userdata)
{
QObject::connect(this, &SubWindow::SendToControllerSignal,
appcontroller_, &Appcontroller::Slot);
emit SendToControllerSignal(userdata);
// how to get a callback (targeted to me/this) from this,
// if the appcontroller does not know me? what is de way?
};
TL;DR: Connections should be made outside of the components. To compose the parts of your system, you instantiate the objects, and then connect them for desired functionality. The objects should otherwise have no knowledge of each other.
Thus, the only means of communication between the objects are signals and slots.
All GUI classes know the app controller and can call its public slots to send data to it that should be stored in the model
Nope.
The GUI classes should know nothing. When a GUI class needs something, it emits a signal. When a GUI class is supposed act on something (e.g. a change in the model), it exposes that as a slot.
I am propagating the knowledge of the app controller to the MasterWindow
Why? The MasterWindow exposes its functionality via signals and slots. Composing it into a bigger system is accomplished by signal/slot connections. No other knowledge is needed.
The app controller takes the data and calls the appropriate database to store it.
Does there even need to be a controller? All it seems to do is act like a signal-slot connection. You can directly connect the GUI classes to the database, and the controller could be what sets the connections up initially.
Otherwise, the application controller can act as a viewmodel, i.e. a QAbstractItemModel that adapts the model exposed by the database, and tweaks it for display/interaction (e.g. adds color properties, icons, etc.).
The database classes check the data and return a bool to the app controller to tell if the data was okay or not.
The database classes should expose slots that are used to modify the database state. They should also expose signals that indicate any changes. To indicate failure, the database can indicate a "change" with the same value.
how to get a callback (targeted to me/this) from this, if the appcontroller does not know me? what is de way?
The signals from the model/database are connected to the GUI classes. A GUI class can go into a "change pending" state once it emits a "change requested" signal. It will then react accordingly when its "new value" slot is called with the updated value: if the value didn't change, it indicates a failure, otherwise it indicates success. If it didn't request a change, it simply updates the displayed value - something else changed it.
This can be all done using nothing more than the Q_PROPERTY mechanism, and the change notification signals.
If the values aren't simple discretes, but rather have some structure, expose those as indices in a custom QAbstractItemModel. Each GUI item can then act on one or more model indices: requesting the changes, and reacting to value updates.
Multiple GUI elements can be hooked up to the same database variable (or no GUI elements!), and the GUI must support this and update its state to reflect the state of the model.
The "tickets" or "request identifiers" you propose are mostly spurious. The requesting GUI element has enough state to know that it requested a change, and can always act predictably on subsequent feedback from the model/database.

MVC design pattern with cocos2dx and cpp

I'm working with cocos2dx on Xcode, I have a question about cpp MVC design pattern.
when my model value changes internally, should I pass the changed value with the event or should i inform the view and let the view do the request for those values through the controller?
I'm asking is this appropriate to used in MVC design pattern.
I create my controller (which inherits from ViewDelegate and Scene) using the static Method to create it. Within the init method in controller, I used View's static method to create instance. I Then set delegate(ViewDelegate*) and pass a reference of Controller. This way the view can use the ViewDelegate reference to access the methods declared as a virtual methods in ViewDelegate. Controller can access View with its instance, which was created before.
On the other side , I create my model as a singleton. Used it in side of my controller and when the value in model changes internally, I use event dispatcher to dispatch a Event telling the View it has changed.

Should this be in model or view?

I am using QFileSystemModel to populate my tree view. User can right click on a tree node (a folder) and perform an operation (exports all certain data files under this folder).
I have this export under the on_tree_clicked() but I feel like this operation belongs to model.
Will it be better if I derive my own QFileSystemModelWithExportfrom QFileSystemModeland added the export function? From on_tree_clicked(), I then just call it?
Is there another way to do this nicely? I want my on_tree_clicked() to be shorter and cleaner.
Also I am quite new to Qt, how do we derive from Qt core class like QFileSystemModel? When I am adding class, it lets me derive from QObject, QWidget etc but not from any model class.
Your UI should only deal with UI problems. i.e. button presses, user interaction.
This should then send it through to your model which actually executes the code.
Think of it this way, if your export to file takes, lets say 5 seconds, that's 5 seconds you can't use your UI for because that thread is doing the write to file. IF you have this model you have the opportunity to multi thread that particular event and keep your UI responsive whilst performing actions.
Code wise:
onTreeClicked() can be fairly short. It could perform the following:
myModel->writeDataFromNodeToFile();
& then inside that function you can have all the functionality you need to write to file. Open/Close/stream data etc

Is it fine to change model data internally before displaying views?

Is it fine to change model data internally before displaying views? For example
struct MainWindow : QMainWindow
{
MainWindow()
{
mTreeView->setModel(mModel);
mModel->appendChild(...); // No beginInsertRows() and similars are called
}
};
Although the model is set to the view before changing the model data, the view is not displayed since it is done in the constructor of main window. If the view is updated when it is displayed, I think the code should be okay.
When the model is already connected to one or more views I totally recommend calling the corresponding begin... and end... methods before and after the model modification. Those functions emit the signals which connected views (or proxies) must handle before and after the data is modified. Otherwise, the views may end up in an invalid state.
When no views (or proxies) are connected it is safe to do so.
It is fine to do so - your program will not crash, at least. However when you add new items to the model in the way you show in your example, your view will not display the update, especially if you do not use beginInsertRows().
If you want the view properly show the actual data, try to set model after you insert items in it. Otherwise you will need to call beginInsertRows() and endInsertRows() in your model class.

MVC and co-dependent classes in c++

EDIT:
what I did instead was to move the "Main Window" creation and message handler into the controller, now only controller needs to know about Model and View. Since main window messages are processed in the controller itself, it can easily call view to change, and call model to do the logic, view never needs to call model, and if model needs to talk to View, then there are 3 options:
It can do so by returning a value to the calls from Model and then Model calls View according to what is returned from Model.
Model can post WM_APP messages to the main window and then Model calls View accordingly.
If the changes are very small, for instance, changing text of a static control, the Controller can pass handles to those controls to Model and Model can do the changes itself.
Any advices ?
I am trying to understand how MVC work in c++ and pure winapi, so am developing a demo app, and trying to implement my own interpretation/version of MVC.
The idea is to keep controller in total control, where everything is relayed through the controller.
Design :
Every class will be in it's own file .h and .cpp
Our main.cpp,view classes and model classes all will only be able to communicate to controller and controller only, there won't be any communication between then directly.
The view classes(there will be more then 1 gui(child windows) including the main window gui) will only create, show, hide, and destroy the windows(views) the messageloop of the main window and any sub or superclassesed child window will reside either in the controller folder or in the model folder.
Controller will further have sub folders with files views.h, views.cpp for communicating to view classes and model.h, model.cpp for communicating to model classes, similar in structure as in views.
Model will have files with different logics related to the application in different files.
It will look something like :
Problem :
There are too many co-dependent classes in different files.
What kind of approach would you suggest, I want to keep the idea of "Everything relaying through controller", if possible.
What's missing is some kind of abstract interfaces for the view and model to communicate. I.e., you rely on concrete types for communication.
This can be solved in a few different ways:
Abstract base classes as listeners/observers, (i.e. IModelListener, IViewListener) which the controller implements.
Events (i.e. ValueEnteredEvent from view and ValueChangedEvent from model).
Slots & signals ala Qt (or Boost), which allows a listener to connect to single output methods of an object.
The controller connects to the view and model object respectively, using whatever method you prefer. Hence, these do not know about the controller directly, they only talk to these given interfaces.
Avoid concrete dependencies & connections.
Abstract them away through interfaces (defined by the object it self)
Make sure each object knows as little as possible (but no less) in order to communicate effectively with it's peers.
I believe you can do this using pipes
The controller will have open pipes to the model class and the view class.
The view will have open pipes to the child view classes.
When a child view makes a change to the data, it sends the change to the main view through the pipe.
The view in turn sends the change to the controller through the pipe.
The controller updates the model by writing to the pipe.
The model updates the data and sends the refreshed data to the controller.
The controller sends the refreshed data to the main view.
The view then sends the refreshed data to the child views.
All communication is done by reading and writing to the respective pipes.
What I'm doing on MVC pattern is I create a ViewDelegate which is an abstract class. Make my controller inherited from ViewDelegate, and set controller as View's delegate.
Class ViewDelegate{
Public:
Virtual void onViewCallBack = 0;
}
Class controller : public ViewDelegate{
Public:
Static Controller* create();
Private:
Bool init();
Void onViewCallBack();
}
Class view {
Public:
static view* create();
Bool initWithDelegate(ViewDelegate*)
Private:
Bool init();
}
Use the delegate in View to call method declare in Controller.