oopuser-interfacedialogdm-script

Is It Possible to Use One Class per Tab to Define a UI?


I'm working on a GUI that consists of several tabs, and I'm aiming to make the code more modular. Instead of putting all functions into a single class (which becomes very long and can lead to naming conflicts among widget functions), I tried to adopt the following approach:

However, I encountered some issues and have a few questions:

  1. Change Method: Where should the change method be defined? Should it be inside each tab class or managed elsewhere?
  2. Listeners: Where is the best place to define the listener? Is it more appropriate to have it in the tab class, or should it be centralized in the uiframe class?
  3. Inter-Tab Communication: If I want the change method of tab class A to control or affect something in tab class B, what is the best way to implement that? Is it possible, and if so, how?

Failed Attempts & Observations:

Additionally, if anyone has suggestions on how to make the uiframe class more elegant or if there is any Python code or libraries that can easily generate Gatan UI, please let me know.


Solution

  • As you have discovered, classes that define the properties and behavior of custom DM dialogs are inherently long and can get quite complex. I don't think there is any way to truly avoid this. Any such custom dialog class will normally define and implement dozens of methods. However, these member methods are probably your best hope for modularizing your dialog code.

    Your question is probably much farther ranging than you may realize and you might need to break it down into several parts in order to cover all the details involved. Nevertheless, I will start by providing a high-level strategy and some clarifications about classes, objects, and functions.

    It is certainly a good idea to modularize the generation of the various components of any DM dialog that is based on the UIFrame class. It is usually sufficient to do so via functions (methods) defined within one's custom dialog class.

    First, some general comments about concepts and terminology. It is helpful to realize that UIFrame is a base class and that the code one writes to define, pose, and support a custom dialog is an extension of that base class. We say that one's custom dialog class is "derived from" UIFrame. When one calls Alloc() on a custom dialog class, this returns an Object which is a specific instance of one's custom dialog class, i.e. a displayed and running UI panel with active event handling. Note that one can launch multiple instances of a given dialog using the same custom dialog (UIFrame-derived) class.

    Going back to your specific question about modularizing the tab code in your custom dialog class, the words you use to describe what you would like to achieve [... to use one class to build one tab (called tab class), which returns a TagGroup] are quite revealing. What they describe is really the action of a function, i.e. the fact that it returns a TagGroup which is the tab element descriptor. Thus, my suggestion would be to simply define each of your dialog tabs with a different function (i.e. method of your custom dialog class). If they are similar enough, you might even be able to parameterize your tab definition function so that you can use it to return a (different) descriptor TagGroup for each of your specific tabs.

    As for your questions about event handling (i.e. change methods and listeners), ultimately, these methods will always need to be part of your custom dialog class because DM always invokes the change methods by means of its reference to your specific dialog object (i.e. a given instance of your custom dialog class). Of course, these event handling methods can ultimately use other methods/functions (and even other objects) to carry out their work, but you will need to define and implement methods in your custom dialog class that DM will call in response to events and changes within your custom GUI object.