Package: easy-mvp
easy_mvpDescriptioneasy_mvpis a package that makes it easy to build desktop applications
usingMVPpattern,PythonandPyQt5. This is achieved by using
a set of classes and practices similar to those used in theAndroid framework.The basic idea behind this package is to open a presenter from
another presenter and that the new presenter fills the window for
complete. This is similar toAndroid applications, which
when opening a newActivity, they replace the old one with the new one.
If the Back button is pressed, then the newActivityis removed
and the old one reappears on the screen. This gives the impression
that there is astack of Activity.In addition,easy_mvpoffers the possibility of doing the abovein more than
a window, since desktop applications are very different toAndroid apps.InstallationTo install this package you need to havePythoninstalled in your system.
Then you can run this command to install this package:pipinstalleasy_mvpExplaining the mechanismThe following explanations are reflected indemo.pyprogram.The application model created byeasy_mvpis like this:TheApplicationManagerclass is theentry pointof the program. This
class is the one that knows the windows, creates them and destroys them. Each
window holds astack of presenters. In this way it is implemented
the same behavior that Android applications have. ClassIntentis used totransitionfrom one presenter to another,
regardless of whether the new presenter is started in a new window.The behavior of the windows is represented as follows:As you can see thewindow has a stack of presenters, the
which are attached to their views, thereforeall the
presenters must possess a view. Again we can see that the classIntentis the one that allows to add a newpair of presenter-viewto the window stack. For this mechanism to work, the presenter
classes mustinherit from the AbstractPresenterclass.AbstractPresenterhas several methods to open new presenters,
close the current presenter and to handle certain flows within the
application, such as when a presenter is going to be initialized, hidden,
or closed.The flow of events in a class that inherits from AbstractPresenter is like this:The_on_initializemethod is the first method called in theAbstractPresenterclass.
Here the instance variables of the presenter must be initialized. Also, you must
create the instance of the view that corresponds to the presenter. Once created,
the view instance must be set with the_set_view(view)method, from
this way the view is made accessible to the rest of the classes ineasy_mvp environment.
The view can be obtained with theviewproperty orget_viewmethod ofAbstractPresenter, if it was set
by_set_view(view)first.Theon_view_shownmethod is called just after the presenter view
is displayed in the graphical interface. In this method the data should be loaded,
and the tables and forms filled.If on the presenter whose view is visible,_open_other_presenteris called
then another presenter will be created, and this presenter will go to the top of thestack of presenters, and its view will be the only one visible in the graphical interface.
The view of presenter that called_open_other_presenterwill no longer be visible.
Before this last occurs, the calling presenter will receive control of the program
with the methodon_view_covered.If now the top presenter calls _close_this_presenter, then the
presenter view just below it will be visible again, and the
presenter will receive control of the main thread viaon_view_discovered.
In this method the view should be updated due to some change in the model.When the presenter at the top of the stack calls_close_this_presenterreceives the control with theon_closing_presentermethod. In this method
resources should be released and observers removed. After the call toon_closing_presenterthe presenter and the view of the presenter will be
removed, and it will happen what it has been explained previously.
It should be noted that if the presenter who closes is the
only one that exists in the entire application, that is, there is only one
window, and it owns only a presenter then the application will close with
thestatus code 0. To close the program with different code, use theexit_appmethod of AbstractPresenter.Receiving data from presentersA presenter can receive data from another presenter that it has created,
if the second one is closed using the_close_this_presenter_with_result(result_data: dict, result: str = Intent.NO_RESULT)method. In this way, the presenter that is below in the stack receives control of the
program viaon_view_discovered_with_result(action: str, data: dict, result: str)instead ofon_view_discovered. The action parameter is the action that was passed to theIntentwhen
it was ordered to open the new presenter. The result_data is aPython dictionarythat the
presenter who was on top can pass through_close_this_presenter_with_result(result_data: dict, result: str = Intent.NO_RESULT). The result string can be used
to tell the below presenter what happened on top presenter. In this way the below presenter can take different decisions
depending on the result returned by top presenter.Managing global dataData can be created to be accessible throughout the entire application. This is
accomplished with theset_global_data(key: str, data)andget_global_data(key: str)methods ofAbstractPresenter. You can also check if a global data exists with the methodhas_global_data(key: str), which returns True if it exists and False otherwise.Knowing Intent in depthAs explainedIntentis what makes it possible to open new presenters. You can specify
that the new presenter must be opened on a new window usinguse_new_window(use_new_window: bool = False). You can also specify that
if a new window is to be opened, then make it modal or not with the methoduse_modal(self, modal: bool = False).An intent can be specified with an action withset_action(action: str), like so
the new presenter may behave differently depending on the action received.Intentalso allows data to be passed to a new presenter viaset_data(data: dict).
To see examples of howIntentis used, check out thedemo.pyprogram.Acting when user closes windowIf the user clicks the close window button then all presenters in the
presenter stack of the window will receive theon_window_closing(self)call. The first presenter to receive the call will be the one which is
on the stack top, the next to receive the call will be the below presenter.
This flow of calls will occur all the way down through the window stack.
When all presenters have executedon_window_closing(self)then the
window will be closed. If the window that is being closing has child
windows, then all its children will receive theon_window_closing(self)calls in the same way the parent window received it.This method is useful to close database connections, close files and
stop threads. All you must close goes here.Customize window titleEvery presenter can change the window title. This is useful because each presenter will do
a different task, and therefore you would like to change the title of the window depending
on it.You can reimplement the methodget_default_window_title(self)to set a custom
window title. You only have to setreturn 'My custom window title'in the method's
body. This method will be called before the presenter receives theon_view_show,on_view_discoveredandon_view_discovered_with_resultcalls.
By default, this method returns the'No Title, reimplement get_default_window_title'string.But if you want more power on changing the window title you can use the_set_window_title(self, window_title: str)to immediately change it. After calling
this method the window title can be replaced automatically if the presenter who set it is popped,
or if a new presenter is added on top. This will happen because of the calls toget_default_window_title(self)on below presenter or on the new presenter respectively,
during theeasy-mvpevent flow.Setting application name and window IconYou can set the application name and Window Icon by passing this information to
ApplicationManager constructor:manager=ApplicationManager(app_name='easy_mvp demo',window_icon_path='./demo/view/ui/assets/icon.png')This way the operating system will know the name of your app and its window icon.