Search code examples
qtoopdesign-patternsclass-design

Separating data handling from GUI


I'm developing a network-testing-tool which has a graphical user interface. The problem I'm facing now is, that I can't separate the underlying data from the GUI classes. The application consists of a QMainWindow which then spawns several other QDialogs and has some QWidgets. In each of these classes there is some functionality using QLineEdits, QPushButtons and so on and also data is stored in each class. Right now, in order to use data about a device from, for example, the DeviceDiscovery Widget in the MainWindow I need to use

deviceId = self.widget_deviceDiscovery.devices['devName'].id

instead of being able to store it outside of the whole GUI. But how could I accomplish this? It just doesn't seem right to store the data in the GUI classes.


Solution

  • It just doesn't seem right to store the data in the GUI classes.

    Of course not, but then again I don't see how it is possible to store anything in the UI. Data is stored in files. If you mean that you are getting content from the view objects and applying it when some action happens, that is usually OK(ish).

    For example - you have a 'login' screen with two editable text views and a button. Upon button click somewhere in the code there is a component (usually resembles an Observer) which extracts the values from the text views and initiates the login process. That is your standard GUI frameworks and that's OK since these frameworks are actually separated by design as they usually follow the MVC/P patterns. Data and BL are left to be handled by you, because those are obviously application specifics.

    The downside in these frameworks is that testing becomes somewhat hard to accomplish and state is pulled from the widgets. When different UI frameworks are supposed to be supported, state management is re-writing per framework which is an overhead.

    There is a pattern called Presentation Model, which separates the two layers entirely (GUI from Presentation) and lets you handle the two concepts in different layers. Most binding frameworks are built upon this concept.