This section describes how the GUI can be notified when kernel objects and custom kernel objects are modified outside the GUI process. The following topics are covered:
Queries provide a mechanism that allows the GUI process to be notified when data in the kernel change. “Keeping the GUI and commands up-to-date,” Section 6.5.3, describes how you use the registerQuery argument of the AFXGuiCommand constructor. The registerQuery argument is a Boolean flag that specifies whether to register a query automatically on the object being edited by the specified kernel command. If the kernel object specified in the AFXGuiCommand constructor changes, the infrastructure updates the keywords in the GUI with the latest values. As a result, you do not need to register a query explicitly. By default, registerQuery= False, and the query is not automatically registered.
For example,
cmd = AFXGuiCommand(mode,'setValues', mdb.models[%s].parts[%s], True)In this example, if the user changes the current part, the path to the setValues method is updated to reflect the new current part. As a result, when the user clicks OK to commit a customized dialog box, the mode issues a setValues command that modifies the current part.
For objects not directly related to a command, such as a repository, you may wish to register a query yourself. You can register a query on an Abaqus/CAE object using the registerQuery method. This method takes a callback function as an argument. When the object upon which the query is registered changes, the infrastructure automatically calls the function supplied in the registerQuery method. For example,
from abaqusGui import * def onPartsChanged(): print 'The parts repository changed.' keys = mdb.models['Model-1'].parts.keys() print 'The new keys are:', keys mdb.models['Model-1'].parts.registerQuery(onPartsChanged)In the previous example, if a part is created, deleted, renamed, or edited, the onPartsChanged method will be called.
The registerQuery method takes an optional second argument that determines whether or not the callback is called when the query is first registered. By default, this argument is True, and the callback will be called when the query is first registered. If you specify False as the second argument, the query callback is not called when the query is first registered. Delaying the query callback can prevent errors in certain situations; for more information, see “Using registerQuery on kernelAccess proxy objects,” Section 6.8.3.
Since registered queries create “traffic” between the kernel and GUI processes, you should unregister queries when you do not need them. To unregister a query, use the unregisterQuery method and pass the same arguments that you used in the registerQuery method. In most cases, you register queries within the show method that you write for your dialog box that needs the queries. Similarly, you unregister queries within the hide method that you write for your dialog box. If you do not unregister a query and the query fires when the dialog box is not posted, the application may abort if the callback tries to modify a widget in the dialog box.
If the user creates, deletes, renames, or edits a part in the following example, the application will call the onPartsChanged method and update the dialog box:
class MyDialog(AFXDataDialog): ... def onPartsChanged(self): # Code to update the part list # in the dialog box def show(self): from kernelAccess import mdb mdb.models['Model-1'].parts.registerQuery( self.onPartsChanged) AFXDataDialog.show(self) def hide(self): from kernelAccess import mdb mdb.models['Model-1'].parts.unregisterQuery( self.onPartsChanged) AFXDataDialog.hide(self)
It is possible to call the registerQuery method on a kernelAccess module proxy object instead of the abaqusGui proxy object. However, internally the query is always registered on the abaqusGui proxy object. The two kinds of proxy objects are not always perfectly synchronized. In most cases, this will not matter. However, it can cause a problem if the query is registered while a change is being made on the kernel. For example,
from kernelAccess import mdb def onPartsChanged(): print 'The parts repository changed.' keys = mdb.models['Model-1'].parts.keys() # OK print 'The new keys are:', keys if keys: mdb.models['Model-1'].parts[keys[0]].registerQuery(onPartsChanged) # Not OK # Internally the registerQuery method will be called on abaqusGui.mdb... mdb.models['Model-1'].parts.registerQuery(onPartsChanged)If a changeKey command that affects the names in the parts repository is subsequently issued, the above example will fail. The keys (part names) are obtained using the kernelAccess mdb proxy object and contain the changed name. However, the registerQuery method—based on the abaqusGui proxy object—does not see the new names until the changeKey command is completed. The registerQuery on the newly named part object (using keys()[0]) is being called within the callback, before the changeKey command is completed, and the callback is using the new name. Since the abaqusGui proxy for the parts repository has not yet been updated, a Keyerror is raised.
Run the above example in the GUI, create a part, then enter the following in the command line interface (CLI):
>>> mdb.models['Model-1'].parts.changeKey('Part-1', 'ROD')You will get the following error:
Traceback (most recent call last): File "path and filename of the example script", line 9, in onPartsChanged mdb.models['Model-1].parts[partNames[0]].registerQuery (onPartsChanged) # Not OK KeyError: 'ROD'The error can cause Abaqus/CAE to stop responding. Setting the second argument on registerQuery to False prevents the callback from being called immediately and prevents this potential error.
To receive notification in the GUI of changes made to custom kernel objects, those kernel objects must make use of special classes provided by the customKernel module. The customKernel module provides the following special classes, all of which are capable of notifying the GUI when the contents of the class changes:
CommandRegister allows you to create general classes. For more information, see “CommandRegister class,” Section 5.6.3 of the Abaqus Scripting User's Manual.
RepositorySupport allows you to create repositories below other repositories. For more information, see “RepositorySupport,” Section 5.6.6 of the Abaqus Scripting User's Manual.
RegisteredDictionary allows you to create custom dictionaries. For more information, see “Registered dictionaries,” Section 5.6.7 of the Abaqus Scripting User's Manual.
RegisteredList allows you to create custom lists. For more information, see “Registered lists,” Section 5.6.8 of the Abaqus Scripting User's Manual.
RegisteredTuple allows you to create custom tuples. For more information, see “Registered tuples,” Section 5.6.9 of the Abaqus Scripting User's Manual.
For more information on the customKernel module, see “Extending the Abaqus Scripting Interface,” Section 5.6 of the Abaqus Scripting User's Manual.