Abaqus二次开发中,可以通过以下两种方法控制控件的使用状态。
(1)通过转换函数addTransition()方便地改变对话框中控件的使用状态,在某个转换机制中会将某关键字的值与指定值进行对比,如果两者匹配,则会向目标对象发送相应的状态控制消息。
(2)采用processUpdates()函数控制控件的使用状态。
一、通过addTransition()控制控件使用状态
1.1 语法
addTransition(target, op, value, tgt, sel, ptr=None)
addTransition(keyword, op, value, tgt, sel, ptr=None)
小tips:op表示比较,大于小于等于之类的,后面会说。
上述两个函数中,当target.getValue() op value或者keyword.getValue() op value指令执行结果为真值时,会将消息地址传递给目标对象tgt(被控对象),从而控制被控对象的使用状态。
1.2 实例展示1:用复选框来控制文本框
本程序将展示用复选框来控制文本框的使用状态,当复选框被勾选时,文本框可编辑,反之,文本框不可编辑。
代码展示:
MKUINT(messageld, messageType)函数可以通过合并消息ID和消息类型来生成消息选择器。
界面文件【test_addTransition_DB.py】
# -* - coding:UTF-8 -*-
from abaqusConstants import *
from abaqusGui import *
from kernelAccess import mdb, session
class test_addTransition_DB(AFXDataDialog):
ID_Mybutton = AFXDataDialog.ID_LAST
def __init__(self, form):
AFXDataDialog.__init__(self, form, 'Test addTransition',
self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
okBtn = self.getActionButton(self.ID_CLICKED_OK)
okBtn.setText('OK')
GroupBox_1 = FXGroupBox(p=self, text='Test addTransition',
opts=FRAME_GROOVE) #创建一个窗口
self.yesno1=FXCheckButton(p=GroupBox_1,
text='Cohesive Element', tgt=form.yesnoKw, sel=0) #创建一个复选框
self.radius1=AFXTextField(p=GroupBox_1, ncols=10,
labelText='radius:', tgt=form.radiusKw, sel=0) #创建一个文本框
self.addTransition(form.yesnoKw, AFXTransition.EQ,
False,self.radius1,
MKUINT(FXWindow.ID_DISABLE, SEL_COMMAND), None)
self.addTransition(form.yesnoKw, AFXTransition.EQ,
True,self.radius1,
MKUINT(FXWindow.ID_ENABLE, SEL_COMMAND), None)
注册文件【test_addTransition_plugin.py】
# -* - coding:UTF-8 -*-
from abaqusGui import *
from abaqusConstants import ALL
import osutils, os
class test_addtransition_plugin(AFXForm):
[
ID_WARNING,
] = range(AFXForm.ID_LAST, AFXForm.ID_LAST+1)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, owner):
# Construct the base class.
#
AFXForm.__init__(self, owner)
FXMAPFUNC(self, SEL_COMMAND, self.ID_WARNING,
test_addtransition_plugin.onCmdWarning)
self.radioButtonGroups = {}
self.cmd = AFXGuiCommand(mode=self, method='',
objectName='', registerQuery=False)
pickedDefault = ''
self.radiusKw = AFXFloatKeyword(self.cmd, 'radius', True)
self.yesnoKw = AFXBoolKeyword(self.cmd, 'yesno',
AFXBoolKeyword.TRUE_FALSE, True, True)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def getFirstDialog(self):
import test_addTransition_DB
return test_addTransition_DB.test_addTransition_DB(self)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def doCustomChecks(self):
# Try to set the appropriate radio button on. If the user did
# not specify any buttons to be on, do nothing.
#
for kw1,kw2,d in self.radioButtonGroups.values():
try:
value = d[ kw1.getValue() ]
kw2.setValue(value)
except:
pass
if self.radiusKw.getValue()<= 0:
showAFXErrorDialog(getAFXApp().getAFXMainWindow(),
'半径必须为正数。')
return False
else:
return True
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def okToCancel(self):
# No need to close the dialog when a file operation (such
# as New or Open) or model change is executed.
#
return False
def onCmdWarning(self, sender, sel, ptr):
if sender.getPressedButtonId() == \
AFXDialog.ID_CLICKED_YES:
self.issueCommands()
elif sender.getPressedButtonId() == \
AFXDialog.ID_CLICKED_NO:
self.deactivate()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Register the plug-in
#
thisPath = os.path.abspath(__file__)
thisDir = os.path.dirname(thisPath)
toolset = getAFXApp().getAFXMainWindow().getPluginToolset()
toolset.registerGuiMenuButton(
buttonText='test_addtransition',
object=test_addtransition_plugin(toolset),
messageId=AFXMode.ID_ACTIVATE,
icon=None,
kernelInitString='',
applicableModules=ALL,
version='N/A',
author='N/A',
description='N/A',
helpUrl='N/A'
)
1.3 实例展示2:用单选框来控制文本框
图形界面文件【test_addTransition_DB.py】
# -* - coding:UTF-8 -*-
from abaqusConstants import *
from abaqusGui import *
from kernelAccess import mdb, session
class test_addTransition_DB(AFXDataDialog):
ID_Mybutton = AFXDataDialog.ID_LAST
def __init__(self, form):
AFXDataDialog.__init__(self, form, 'Test addTransition',
self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
okBtn = self.getActionButton(self.ID_CLICKED_OK)
okBtn.setText('OK')
GroupBox_1 = FXGroupBox(p=self, text='Test addTransition',
opts=FRAME_GROOVE)
self.yesno1=FXCheckButton(p=GroupBox_1,
text='Cohesive Element', tgt=form.yesnoKw, sel=0)
self.radius1=AFXTextField(p=GroupBox_1, ncols=10,
labelText='radius:', tgt=form.radiusKw, sel=0)
FXRadioButton(p=GroupBox_1, text='YES', tgt=form.yesnoKw1, sel=11)
FXRadioButton(p=GroupBox_1, text='NO', tgt=form.yesnoKw1, sel=12)
self.length1=AFXTextField(p=GroupBox_1, ncols=10,
labelText='length:', tgt=form.lengthKw, sel=3)
self.addTransition(form.yesnoKw, AFXTransition.EQ,
False,self.radius1,
MKUINT(FXWindow.ID_DISABLE, SEL_COMMAND), None)
self.addTransition(form.yesnoKw, AFXTransition.EQ,
True,self.radius1,
MKUINT(FXWindow.ID_ENABLE, SEL_COMMAND), None)
self.addTransition(form.yesnoKw1, AFXTransition.EQ,
11, self.length1,
MKUINT(FXWindow.ID_ENABLE, SEL_COMMAND), None)
self.addTransition(form.yesnoKw1, AFXTransition.EQ,
12, self.length1,
MKUINT(FXWindow.ID_DISABLE, SEL_COMMAND), None)
注册文件【test_addTransition_plugin.py】
# -* - coding:UTF-8 -*-
from abaqusGui import *
from abaqusConstants import ALL
import osutils, os
class test_addtransition_plugin(AFXForm):
[
ID_WARNING,
] = range(AFXForm.ID_LAST, AFXForm.ID_LAST+1)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, owner):
# Construct the base class.
#
AFXForm.__init__(self, owner)
FXMAPFUNC(self, SEL_COMMAND, self.ID_WARNING,
test_addtransition_plugin.onCmdWarning)
self.radioButtonGroups = {}
self.cmd = AFXGuiCommand(mode=self, method='',
objectName='', registerQuery=False)
pickedDefault = ''
self.radiusKw = AFXFloatKeyword(self.cmd, 'radius', True)
self.yesnoKw = AFXBoolKeyword(self.cmd, 'yesno',
AFXBoolKeyword.TRUE_FALSE, True, True)
self.lengthKw = AFXFloatKeyword(self.cmd, 'length', True)
if not self.radioButtonGroups.has_key('yesno'):
self.yesnoKw1 = AFXIntKeyword(None, 'yesnoDummy', True)
self.yesnoKw2 = AFXStringKeyword(self.cmd, 'yesno', True)
self.radioButtonGroups['yesno'] =(self.yesnoKw1, self.yesnoKw2, {})
self.radioButtonGroups['yesno'][2][1] = 'YES'
if not self.radioButtonGroups.has_key('radiobutton'):
self.yesnoKw1 = AFXIntKeyword(None, 'yesnoDummy', True)
self.yesnoKw2 = AFXStringKeyword(self.cmd, 'yesno', True)
self.radioButtonGroups['yesno'] =(self.yesnoKw1, self.yesnoKw2, {})
self.radioButtonGroups['yesno'][2][2] = 'NO'
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def getFirstDialog(self):
import test_addTransition_DB
return test_addTransition_DB.test_addTransition_DB(self)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def doCustomChecks(self):
# Try to set the appropriate radio button on. If the user did
# not specify any buttons to be on, do nothing.
#
for kw1,kw2,d in self.radioButtonGroups.values():
try:
value = d[ kw1.getValue() ]
kw2.setValue(value)
except:
pass
if self.radiusKw.getValue()<= 0:
showAFXErrorDialog(getAFXApp().getAFXMainWindow(),
'半径必须为正数。')
return False
else:
return True
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def okToCancel(self):
# No need to close the dialog when a file operation (such
# as New or Open) or model change is executed.
#
return False
def onCmdWarning(self, sender, sel, ptr):
if sender.getPressedButtonId() == \
AFXDialog.ID_CLICKED_YES:
self.issueCommands()
elif sender.getPressedButtonId() == \
AFXDialog.ID_CLICKED_NO:
self.deactivate()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Register the plug-in
#
thisPath = os.path.abspath(__file__)
thisDir = os.path.dirname(thisPath)
toolset = getAFXApp().getAFXMainWindow().getPluginToolset()
toolset.registerGuiMenuButton(
buttonText='test_addtransition',
object=test_addtransition_plugin(toolset),
messageId=AFXMode.ID_ACTIVATE,
icon=None,
kernelInitString='',
applicableModules=ALL,
version='N/A',
author='N/A',
description='N/A',
helpUrl='N/A'
)
二、使用processUpdates()控制控件使用状态
在某些情况下,使用简单的 addTransition()函数无法满足使用要求,例如某个控件的状态取决于另外两个或者多个控件的状态,此时采用简单的addTransition()函数无法实现对控件使用状态的控制。这种情况下,可以使用processUpdates()函数来实时更新GUI控件的使用状态,在每次GUI更新时都会调用processUpdates()函数,因此processUpdates()函数内部应尽量避免使用耗时的函数。一般使用processUpdates()函数结合disable()和 enable()来控制控件是否可用。
当需要用多个控件的信息来控制另外某一个或者多个控件的使用状态时,只需要processUpdates()函数内部判断语句中增加几个判断项即可。
2.1 实例
当没有勾选的时候,radius和测试按钮都不能使用。勾选后,两个都可被编辑。
2.2 代码展示
界面文件【testdisable_standardDB.py】
# -* - coding:UTF-8 -*-
from abaqusConstants import *
from abaqusGui import *
from kernelAccess import mdb, session
class testdisable_standardDB(AFXDataDialog):
ID_Mybutton = AFXDataDialog.ID_LAST
def __init__(self, form):
# Construct the base class.
#
AFXDataDialog.__init__(self, form, 'Test Disable',
self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
okBtn = self.getActionButton(self.ID_CLICKED_OK)
okBtn.setText('OK')
GroupBox_1 = FXGroupBox(p=self, text='Test Disable',
opts=FRAME_GROOVE)
self.testdisable1=FXCheckButton(p=GroupBox_1,
text='Test Disable', tgt=form.testdisableKw, sel=0)
self.radius1=AFXTextField(p=GroupBox_1, ncols=10,
labelText='radius:', tgt=form.radiusKw, sel=0)
self.button1=FXButton(p=self, text='测试', ic=None, tgt=self,
sel=self.ID_Mybutton,
opts=BUTTON_NORMAL,
x=0, y=0, w=0, h=0, pl=0) #自定义push button
self.form=form
def processUpdates(self):
if self.form.testdisableKw.getValue() == False:
self.button1.disable()
self.radius1.disable()
else:
self.button1.enable()
self.radius1.enable()
注册文件【testdisable_standard_plugin.py】
# -* - coding:UTF-8 -*-
from abaqusGui import *
from abaqusConstants import ALL
import osutils, os
###########################################################################
# Class definition
###########################################################################
class testdisable_standard_plugin(AFXForm):
[
ID_WARNING,
] = range(AFXForm.ID_LAST, AFXForm.ID_LAST+1)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, owner):
# Construct the base class.
#
AFXForm.__init__(self, owner)
FXMAPFUNC(self, SEL_COMMAND, self.ID_WARNING,
testdisable_standard_plugin.onCmdWarning)
self.radioButtonGroups = {}
self.cmd = AFXGuiCommand(mode=self, method='',
objectName='', registerQuery=False)
pickedDefault = ''
self.testdisableKw = AFXBoolKeyword(self.cmd, 'testdisable', AFXBoolKeyword.TRUE_FALSE, True, True)
self.radiusKw = AFXFloatKeyword(self.cmd, 'radius', True)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def getFirstDialog(self):
import testdisable_standardDB
return testdisable_standardDB.testdisable_standardDB(self)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def doCustomChecks(self):
# Try to set the appropriate radio button on. If the user did
# not specify any buttons to be on, do nothing.
#
for kw1,kw2,d in self.radioButtonGroups.values():
try:
value = d[ kw1.getValue() ]
kw2.setValue(value)
except:
pass
if self.radiusKw.getValue()<= 0:
showAFXErrorDialog(getAFXApp().getAFXMainWindow(),
'半径必须为正数。')
return False
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def okToCancel(self):
# No need to close the dialog when a file operation (such
# as New or Open) or model change is executed.
#
return False
def onCmdWarning(self, sender, sel, ptr):
if sender.getPressedButtonId() == \
AFXDialog.ID_CLICKED_YES:
self.issueCommands()
elif sender.getPressedButtonId() == \
AFXDialog.ID_CLICKED_NO:
self.deactivate()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Register the plug-in
#
thisPath = os.path.abspath(__file__)
thisDir = os.path.dirname(thisPath)
toolset = getAFXApp().getAFXMainWindow().getPluginToolset()
toolset.registerGuiMenuButton(
buttonText='testdisable_standard',
object=testdisable_standard_plugin(toolset),
messageId=AFXMode.ID_ACTIVATE,
icon=None,
kernelInitString='',
applicableModules=ALL,
version='N/A',
author='N/A',
description='N/A',
helpUrl='N/A'
)