7.3 Form modes

A form mode gathers input from the user using one or more dialog boxes. This section describes the two methods used by forms for posting dialog boxes. The following topics are covered:


7.3.1 Form example

The following example illustrates how to write a form mode. This first example contains only one dialog box; a subsequent example will extend this form to include multiple dialog boxes.

from abaqusGui import *
from plateDB import PlateDB

class PlateForm(AFXForm):

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __init__(self, owner):
    
        AFXForm.__init__(self, owner)
        
        self.cmd = AFXGuiCommand(
            self, 'Plate', 'examples')
        self.nameKw = AFXStringKeyword(
            self.cmd, 'name', TRUE)
        self.widthKw = AFXFloatKeyword(
            self.cmd, 'width', TRUE)
        self.heightKw = AFXFloatKeyword(
            self.cmd, 'height', TRUE)
        
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def getFirstDialog(self):
    
        self.cmd.setKeywordValuesToDefaults()
        return PlateDB(self)


7.3.2 Form constructor

You begin writing a form mode by deriving a new class from AFXForm. In the body of the AFXForm constructor you must call the base class constructor and pass in the owner, which is the module or toolset GUI to which this form belongs.

You then define the commands and keywords that the mode will use. The keywords are stored as members of the mode so that they can be accessed by dialog boxes. If you set registerQuery=TRUE in the AFXGuiCommand constructor, the mode will query the kernel object specified by the command when it is activated and will automatically set the values of the command's keywords. For more information, see Keeping the GUI and commands up-to-date, Section 6.5.3. If there is no kernel object associated with your command (for example, when creating a new object), you can set the keyword values by specifying a default value in the constructor.

If you have a default object that you want to use to reestablish default values for the dialog box, you can use the mode’s registerDefaultsObject method to register an object whose values will be queried when the user presses the Defaults button in the dialog box. For more information, see Defaults objects, Section 6.5.15.

By default, dialog boxes are posted as modeless or nonmodal. You can change the behavior by calling setModal(TRUE) to have a dialog box posted as modal. In most cases you set the behavior only once; however, you can change the behavior as often as needed by calling the setModal method in the getFirstDialog or getNextDialog methods. For more information, see Modal versus modeless, Section 5.2.


7.3.3 getFirstDialog

You must write the getFirstDialog method for your mode. The getFirstDialog method should return the first dialog box of the mode. In Form example, Section 7.3.1, a pointer to the form is passed into the dialog box constructor. The dialog box will use this pointer to access the mode's keywords.

If you want the same default values to appear every time you post the dialog box, you must call the setKeywordValuesToDefaults() method before returning the dialog box, as shown in Form example, Section 7.3.1.


7.3.4 getNextDialog

If your mode contains more than one dialog box, you must write the getNextDialog method in addition to the getFirstDialog method. The previous dialog box is passed into the getNextDialog method so that you can determine where the user is in the sequence of dialog boxes and act accordingly. The getNextDialog method should return the next dialog box in the sequence, or it should return None to indicate that it has finished collecting input from the user. The following example is a modified version of the example in getFirstDialog, Section 7.3.3, that illustrates how inputs are collected from the user in a series of three dialog boxes rather than just one:

def getFirstDialog(self):
    
    self.dialog1 = PlateDB1(self)
    return self.dialog1
       
def getNextDialog(self, previousDb):
    
    if previousDb == self.dialog1:
        self.dialog2 = PlateDB2(self)
        return self.dialog2
        
    elif previousDb == self.dialog2:
        self.dialog3 = PlateDB3(self)
        return self.dialog3
        
    else:
        return None


7.3.5 Collecting input from the GUI

To collect input from the user via the GUI, the keywords defined in the mode must be connected to widgets in the dialog box. The AFXDataDialog class takes a mode argument in its constructor. Because the form stores keywords, the dialog box can access these keywords and assign them to be targets of widgets in the dialog box. As a result, the GUI can update the keywords; or, if the kernel is updated while the dialog box is posted, the keywords can update the GUI. For more information, see Chapter 5, Dialog boxes.” The following example shows how the form's keywords are connected to the widgets in the dialog box:

class PlateDB(AFXDataDialog):
    
    def __init__(self, mode):

        AFXDataDialog.__init__(self, mode, 'Create Plate', 
            self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
        
        va = AFXVerticalAligner(self)
        AFXTextField(va, 15, 'Name:', mode.nameKw, 0)
        AFXTextField(va, 15, 'Width:', mode.widthKw, 0)
        AFXTextField(va, 15, 'Height:', mode.heightKw, 0)