lundi 4 mai 2020

Design pattern for a PyGObject multithreaded GUI built with Glade - Linux

Actual situation:

I am working on a multi-threaded GUI application, where the layout is completely built with Glade. All the layout windows reside in one .glade file. The .glade file has multiple windows, such as login, dashboard, message dialog, etc. Each window has a pre-defined signal that must be implemented in code.

In my python code, I import the layout via the Gtk.Builder class (add_from_file), I then add a class with all the event handlers (as described in pytgtk manual). I then proceed on displaying the windows accordingly to certain criteria (if the user has already initialized a profile then display the dashboard window, otherwise display the login window).

The GUI does not make use of a database, but rather all configurations are read and written to/from local files.

As it is at the moment, the GUI works well, nothing to complain about the UX. The only part that I would like to improve is the code, I feel like it is too brittle. I was thinking about implementing a design-pattern, but I find it hard on where or how to start.

The biggest obstacle here is that, I have never worked with design patterns. OO is not a foreign concept for me, but this is my first time at building a GUI so I have almost no experience with design patterns.

What I have found:

I have found that python GUI developers generally use one of the following patterns: MVVM, MVC, MVP, Publisher-subscriber and the Observer pattern described here.

I search through stackoverflow and some other pages, but the closest I get is through the following sources:

GTK3 &Python interactive - architecture of classes - PopupMenu Of GTK3 on matplotlib Canvas: The code resembles to have a certain architectural pattern (MVP). I was thinking maybe somehow mimicking this pattern since it seems the one that works best for my use case. From my understanding it seems that:

  • View Class: Consists of all the glade objects.
  • View Handler: Consists of all Event Handlers/Signals.
  • Controller: Initializes the windows.
  • Model: Information is missing about the model.

Design Pattern for Multithreaded GUI Application: Explains a similar thing to what I am trying to achieve, although I am not using a timer in the main thread with flags.

How do I coherently organize modules for a PyGTK desktop application?: The author is working on a PyGTK application and has issues organizing code. Some users suggest using the python gtkmvc package for better code and file management, but that package does not work with Python3 and Gtk3, although some attempted to port it to Gtk3 though without success since they got dropped some time after. Other users mention Kiwi but that one is also a project that is no longer maintained. More info was found here: Python GTK MVC

Python: Callbacks, Delegates, … ? What is common?: The authors questions is a bit what I am also asking here. Below the question, a specific user introduces the observer pattern and then proceeds to show some code, on how the observer pattern could be achieved. Since I do not have experience with design patterns, I was unsure if something was omitted (or missing) or not, thus not sure how it could be implemented with my code.

How do I make a GUI using the model/view/controller method?: Here the author is asking almost exactly the same questions as I am. A user below mentions the ToyMVC, but that package is made for TKinter, plus it is no longer existent. I have although found this.

What I have done (up until this point):

I have already started breaking apart the .glade file. Instead of having one single .glade file, I broke it into multiple .glade files, ex: dashboard_window.glade, login_window.glade, etc. This in turn gave the the flexibility of creating classes for each window, thus having event handlers being connected only to its own object.

How the code was organized before refactoring process started.

How the code is organized during refactoring process.

Lastly:

Having said this, I hope that someone could give me some suggestions or guidance on how to proceed. What I should be doing and what I should be avoiding. What are the advantages or disadvantages. Should I structure my code some other way ? Is it even worth pursuing a design pattern ?

Thank you for your time.

Aucun commentaire:

Enregistrer un commentaire