[toc]session
1. GUI开发简介
Abaqus GUI程序开发时,能够采用两种方式建立GUI图形界面。 (1)使用RSG对话框构造器建立 (2)使用Abaqus GUI工具包建立 RSG对话框构造器是(RSG dialog Builder)是Abaqus/CAE内嵌的GUI插件开发辅助工具,位于Abaqus/CAE主视图“Plug-ins”菜单下的“Abaqus”子菜单中的 "RSG dialog Builder" ,点击后进入下图所示的界面。在该界面中,用户能够建立新的对话框,选择并编辑控件,查看对话框的效果,关联插件执行的内核文件等。该工具使用快捷方便,是插件开发很高效的辅助工具,可是RSG对话框构造器自身的控件种类不多,一共只用22种,对于简单的GUI开发程序基本都能知足。 app
对于复杂的GUI程序,须要用到更多的控件,此时RSG对话框没法知足需求,须要采用第二种GUI图形界面的建立方式,即直接在源程序文件中编辑GUI命令。ide
插件程序通常包括4个文件 (1)注册文件~_plugin.py
(2)图形界面文件~DB.py
(3)内核执行文件~Modul.py
(4)图标文件~.png
函数
2. 目标和消息
2.1消息类型和消息ID
Abaqus GUI工具包是经过目标/消息(target/message)机制实现GUI对象之间交互,全部的控件均可以发送消息给其余的控件,也能够接收来自其余控件的消息。一个消息通常包括两部分:消息类型和消息ID。消息类型指发生事件的类型,消息ID表示消息的发送者。 Abaqus GUI工具包中的大部分控件都能指定目标和消息ID的变量,即便某种控件没有指定目标和ID的变量,也能够经过setTarget和SetSelector方法来设定其目标和ID。 例如:工具
FXButton(parent,'Label',tgt=sef,sel=self.ID_1)#建立一个按钮 groupBox = FXGroupBox(parent)#建立一个控件盒,自身没法设置目标和ID groupBox.setTarget(self)#设置目标 groupBox.SetSelector(self.ID_2)#设置其消息ID
控件能够发送多种类型的消息,最经常使用的两种消息类型是SEL_COMMAND
和SEL_UPDATE
. SEL_COMMAND类型的消息通常表示某个控件被触发,例如,用户按下了按钮。 SEL_UPDATE类型的消息通常是在某一控件须要请求其目标来更新自身状态时才更新。在自动更新过程当中,每一个控件都会给他的目标发送一个SEL_UPDATE小时,请求自身被更新,经过这种方法来实现应用程序保持最新状态。ui
2.2消息映射
一个消息经过消息映射传递给消息的处理方,用户能够指定接收到某消息类型以及消息ID时所须要调用的方法(onCmdA,其中A表示方法名称)this
消息映射通常经过FXMAPFUNC()
函数来定义,函数具备四个变量,分别为self、消息类型(message type)、消息ID(message ID)以及调用的方法(method name),其中方法名必须由类名来指定。idea
当接收到的消息类型和消息ID与某一个FXMAPFUNC()
函数中定义的消息类型和消息ID匹配时,相应的方法就会被调用。另外,若是须要在消息映射中定义一段范围内的ID,能够采用函数FXMAPFUNCS()
,该函数包括5个参数,分别为self、消息类型(message type)、消息起始ID(message ID)、消息结束ID(message ID)以及调用的方法(method name)。 另外,用户可使用SELTYPE
和SELID
函数从消息处理方法获取消息类型和消息ID。spa
3. 控件建立
建立新的控件后,而后保存文件,重启Abaqus,在Plug-ins菜单下回出现新的菜单。插件
可参照软件的列子对程序进行相应的修改,例子以下所示。
注册文件:createPlateWithhole_plugin.py
# -* - coding:UTF-8 -*- from abaqusGui import * from abaqusConstants import ALL import osutils, os ########################################################################### # Class definition ########################################################################### class createPlateWithhole_plugin(AFXForm): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def __init__(self, owner): # Construct the base class. # AFXForm.__init__(self, owner) self.radioButtonGroups = {} self.cmd = AFXGuiCommand(mode=self, method='createPlateFunction', objectName='createPlateModul', registerQuery=False) pickedDefault = '' self.partnameKw = AFXStringKeyword(self.cmd, 'partname', True, 'part-1') self.widthKw = AFXFloatKeyword(self.cmd, 'width', True,100) self.heightKw = AFXFloatKeyword(self.cmd, 'height', True,100) self.radiusKw = AFXFloatKeyword(self.cmd, 'radius', True,5) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def getFirstDialog(self): import createPlateWithholeDB return createPlateWithholeDB.createPlateWithholeDB(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 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 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Register the plug-in # thisPath = os.path.abspath(__file__) thisDir = os.path.dirname(thisPath) toolset = getAFXApp().getAFXMainWindow().getPluginToolset() toolset.registerGuiMenuButton( buttonText='建立带孔板', object=createPlateWithhole_plugin(toolset), messageId=AFXMode.ID_ACTIVATE, icon=None, kernelInitString='import createPlateModul', applicableModules=ALL, version='N/A', author='N/A', description='N/A', helpUrl='N/A' )
界面文件:createPlateWithholeDB.py
# -* - coding:UTF-8 -*- from abaqusConstants import * from abaqusGui import * from kernelAccess import mdb, session import os thisPath = os.path.abspath(__file__) thisDir = os.path.dirname(thisPath) ####################################################################### # Class definition ####################################################################### class createPlateWithholeDB(AFXDataDialog): ID_Mybutton = AFXDataDialog.ID_LAST #分配ID def __init__(self, form): AFXDataDialog.__init__(self, form, '带孔板参数化建模程序', self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR) okBtn = self.getActionButton(self.ID_CLICKED_OK) okBtn.setText('OK') GroupBox_1 = FXGroupBox(p=self, text='参数', opts=FRAME_GROOVE) AFXTextField(p=GroupBox_1, ncols=12, labelText='零件名 :', tgt=form.partnameKw, sel=0) AFXTextField(p=GroupBox_1, ncols=12, labelText='宽度(w):', tgt=form.widthKw, sel=0) AFXTextField(p=GroupBox_1, ncols=12, labelText='高度(h):', tgt=form.heightKw, sel=0) AFXTextField(p=GroupBox_1, ncols=12, labelText='半径(r):', tgt=form.radiusKw, sel=0) GroupBox_3 = FXGroupBox(p=self, text='示意图', opts=FRAME_GROOVE) fileName = os.path.join(thisDir, r'planewithhole.png') icon = afxCreatePNGIcon(fileName) FXLabel(p=GroupBox_3, text='', ic=icon) FXMAPFUNC(self, SEL_COMMAND, self.ID_Mybutton, createPlateWithholeDB.onCmdMybutton) 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) def onCmdMybutton(self, sender, sel, ptr): if SELID(sel) == self.ID_Mybutton: #使用SELID函数获取消息ID print 'Button 1 was pressed.' #在DOS界面下输出提示信息 mw = getAFXApp().getAFXMainWindow() mw.writeToMessageArea('Button 1 was pressed.' ) #在abaqus/CAE主窗口下方的提示区显示提示信息 return 1
内核程序:createPlateModul.py
# -* - coding:UTF-8 -*- from abaqus import * from abaqusConstants import * def createPlateFunction(partname, width, height, radius): mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=200.0) mdb.models['Model-1'].sketches['__profile__'].rectangle(point1=(0.0, 0.0), point2=(width, height)) mdb.models['Model-1'].sketches['__profile__'].CircleByCenterPerimeter(center=( width/2, height/2), point1=(width/2+radius, height/2)) mdb.models['Model-1'].Part(dimensionality=THREE_D, name=partname, type= DEFORMABLE_BODY) mdb.models['Model-1'].parts[partname].BaseShell(sketch= mdb.models['Model-1'].sketches['__profile__']) p = mdb.models['Model-1'].parts[partname] session.viewports['Viewport: 1'].setValues(displayedObject=p) del mdb.models['Model-1'].sketches['__profile__'] #几何建立完成 mdb.models['Model-1'].Material(name='AL') mdb.models['Model-1'].materials['AL'].Elastic(table=((70000.0, 0.3), )) mdb.models['Model-1'].HomogeneousShellSection(name='al', preIntegrate=OFF, material='AL', thicknessType=UNIFORM, thickness=1.0, thicknessField='', idealization=NO_IDEALIZATION, poissonDefinition=DEFAULT, thicknessModulus=None, temperature=GRADIENT, useDensity=OFF, integrationRule=SIMPSON, numIntPts=5) f = p.faces faces = f.getSequenceFromMask(mask=('[#1 ]', ), ) region = p.Set(faces=faces, name='Set-2') p.SectionAssignment(region=region, sectionName='al', offset=0.0, offsetType=MIDDLE_SURFACE, offsetField='', thicknessAssignment=FROM_SECTION) #创建材料并赋予属性 session.viewports['Viewport: 1'].partDisplay.setValues(mesh=ON) session.viewports['Viewport: 1'].partDisplay.meshOptions.setValues( meshTechnique=ON) session.viewports['Viewport: 1'].partDisplay.geometryOptions.setValues( referenceRepresentation=OFF) #切换到mesh模块 p = mdb.models['Model-1'].parts[partname] p.seedPart(size=4.0, deviationFactor=0.1, minSizeFactor=0.1) f = p.faces pickedRegions = f.findAt(((width/2, 0.0, 0.0), )) p.setMeshControls(regions=pickedRegions, elemShape=QUAD,algorithm=MEDIAL_AXIS) #设定网格划分格式 p.generateMesh() #网格划分 a = mdb.models['Model-1'].rootAssembly session.viewports['Viewport: 1'].setValues(displayedObject=a) session.viewports['Viewport: 1'].assemblyDisplay.setValues( optimizationTasks=OFF, geometricRestrictions=OFF, stopConditions=OFF) #切换到装配模块 a = mdb.models['Model-1'].rootAssembly a.DatumCsysByDefault(CARTESIAN) p = mdb.models['Model-1'].parts[partname] a.Instance(name=partname+'-1', part=p, dependent=ON) #建立装配实例 mdb.models['Model-1'].StaticStep(name='Step-1', previous='Initial', nlgeom=ON) session.viewports['Viewport: 1'].assemblyDisplay.setValues(step='Step-1') #建立分析步 session.viewports['Viewport: 1'].view.setValues(nearPlane=335.564, farPlane=385.546, width=212.48, height=142.547, viewOffsetX=13.3712, viewOffsetY=-7.13345) a = mdb.models['Model-1'].rootAssembly e1 = a.instances[partname+'-1'].edges edges1 = e1.findAt(((0.0, height/2, 0.0), )) region = a.Set(edges=edges1, name='Set-1') mdb.models['Model-1'].DisplacementBC(name='BC-1', createStepName='Step-1', region=region, u1=0.0, u2=0.0, u3=0.0, ur1=0.0, ur2=0.0, ur3=0.0, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName='', localCsys=None) #施加边界条件 edges1 = e1.findAt(((width, height/2, 0.0), )) region = a.Set(edges=edges1, name='Set-2') mdb.models['Model-1'].DisplacementBC(name='BC-2', createStepName='Step-1', region=region, u1=2.0, u2=UNSET, u3=UNSET, ur1=UNSET, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName='', localCsys=None) #施加位移载荷 mdb.Job(name='Job-hole', model='Model-1', description='', type=ANALYSIS, atTime=None, waitMinutes=0, waitHours=0, queue=None, memory=50, memoryUnits=PERCENTAGE, getMemoryFromAnalysis=True, explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE, echoPrint=OFF, modelPrint=OFF, contactPrint=OFF, historyPrint=OFF, userSubroutine='', scratch='', multiprocessingMode=DEFAULT, numCpus=1, numGPUs=0) #建立job