这个表格内容比较多,之前一直有些逃避,现在学完了其他控件,决定回来补一下。
一、创建表格控件
1.1 基本语法
AFXTable(p,numVisRows,numVisColumns,numRows,numColumns, tgt=None, sel=0,
opts=AFXTABLE_NORMAL,X=0, y=0, w=0, h=0, pl=4, pr=4,
pt=DEFAULT_MARGIN,pb=DEFAULT_MARGIN)
1.2 创建表格并设置属性
先用RSG对话框设计一个表格,并对表格进行保存,建议保存成标准格式:
生成的代码(部分):
还可以对列设置下拉选项:
【tableDB.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 TableDB(AFXDataDialog):
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, form):
# Construct the base class.
#
AFXDataDialog.__init__(self, form, 'Table',
self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
okBtn = self.getActionButton(self.ID_CLICKED_OK)
okBtn.setText('OK')
GroupBox_1 = FXGroupBox(p=self, text='myTable', opts=FRAME_GROOVE)
vf = FXVerticalFrame(GroupBox_1, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X,
0,0,0,0, 0,0,0,0)
# Note: Set the selector to indicate that this widget should not be
# colored differently from its parent when the 'Color layout managers'
# button is checked in the RSG Dialog Builder dialog.
vf.setSelector(99)
table = AFXTable(vf, 5, 6, 5, 6, form.TableKwKw, 0, AFXTABLE_EDITABLE|LAYOUT_FILL_X)
table.setPopupOptions(AFXTable.POPUP_PASTE #允许粘贴
|AFXTable.POPUP_CUT #允许剪切
|AFXTable.POPUP_COPY #允许复制
|AFXTable.POPUP_INSERT_ROW #允许插入行
|AFXTable.POPUP_DELETE_ROW #允许删除行
|AFXTable.POPUP_DELETE_COLUMN #允许删除列
|AFXTable.POPUP_CLEAR_CONTENTS #允许清空
|AFXTable.POPUP_READ_FROM_FILE #允许从外部文件读入
|AFXTable.POPUP_WRITE_TO_FILE #允许写出到外部文件
)
table.setLeadingRows(1) #设置表格首行
table.setLeadingColumns(1) #设置表格首列
table.setColumnWidth(1, 150) #设置第一列的宽度
table.setColumnType(1, AFXTable.FLOAT) #设置第一列的数据类型,后面以此类推
table.setColumnWidth(2, 100)
table.setColumnType(2, AFXTable.FLOAT)
table.setColumnWidth(3, 100)
table.setColumnType(3, AFXTable.FLOAT)
table.setColumnWidth(4, 100)
table.setColumnType(4, AFXTable.FLOAT)
table.setColumnWidth(5, 100)
table.setColumnType(5, AFXTable.FLOAT)
table.setLeadingRowLabels('X\tY\tT1\tT2\tHeading') #设置行表头
table.setStretchableColumn( table.getNumColumns()-1 )
table.showHorizontalGrid(True)
table.showVerticalGrid(True)
table.setColumnJustify(1,table.CENTER) #设置文本居中
table.setColumnJustify(2,table.CENTER)
table.setColumnJustify(3,table.CENTER)
listId = table.addList('yes\tno\tababa\thhh') #设置list列表项,各单元之间用\t隔开
table.setColumnType(3,AFXTable.LIST) #设置第三列为列表类型
table.setColumnListId(3,listId) #在第三列添加列表
二、表格控件右键快捷菜单项设置
创建表格控件时,可以通过设置opts选项参数来实现不同的右键快捷菜单效果,表中列举了几种常用的右键快捷菜单项。
三、表格应用实例
3.1 设置表格行列标题及表格的可编辑性
知识补充,python中的range函数:
3.2 创建分栏表格
# -*- 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 TableDB(AFXDataDialog):
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, form):
# Construct the base class.
#
AFXDataDialog.__init__(self, form, 'Table',
self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
okBtn = self.getActionButton(self.ID_CLICKED_OK)
okBtn.setText('OK')
GroupBox_1 = FXGroupBox(p=self, text='myTable', opts=FRAME_GROOVE)
vf = FXVerticalFrame(GroupBox_1, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X,
0,0,0,0, 0,0,0,0)
# Note: Set the selector to indicate that this widget should not be
# colored differently from its parent when the 'Color layout managers'
# button is checked in the RSG Dialog Builder dialog.
vf.setSelector(99)
table = AFXTable(vf, 5, 6, 5, 6, form.TableKwKw, 0, AFXTABLE_EDITABLE|LAYOUT_FILL_X)
table.setPopupOptions(AFXTable.POPUP_PASTE #允许粘贴
|AFXTable.POPUP_CUT #允许剪切
|AFXTable.POPUP_COPY #允许复制
|AFXTable.POPUP_INSERT_ROW #允许插入行
|AFXTable.POPUP_DELETE_ROW #允许删除行
|AFXTable.POPUP_DELETE_COLUMN #允许删除列
|AFXTable.POPUP_CLEAR_CONTENTS #允许清空
|AFXTable.POPUP_READ_FROM_FILE #允许从外部文件读入
|AFXTable.POPUP_WRITE_TO_FILE #允许写出到外部文件
)
table.setLeadingColumns(1) #设置表格首列
table.setLeadingRows(2) #设置表格第二行为首行
table.setColumnWidth(1, 150) #设置第一列的宽度
table.setColumnType(1, AFXTable.FLOAT) #设置第一列的数据类型,后面以此类推
table.setColumnWidth(2, 100)
table.setColumnType(2, AFXTable.FLOAT)
table.setColumnWidth(3, 100)
table.setColumnType(3, AFXTable.FLOAT)
table.setColumnWidth(4, 100)
table.setColumnType(4, AFXTable.FLOAT)
table.setColumnWidth(5, 100)
table.setColumnType(5, AFXTable.FLOAT)
table.setItemSpan(0,1,1,5) #将第二列到第六列合并
table.setLeadingRowLabels('Coordinates') #设置首行标题
table.setLeadingRowLabels('X\tY\tT1\tT2\tT3',1) #设置行表头
table.setStretchableColumn( table.getNumColumns()-1 )
table.showHorizontalGrid(True) #显示横栅栏
table.showVerticalGrid(True) #显示数栅栏
table.setColumnJustify(1,table.CENTER) #设置文本居中
table.setColumnJustify(2,table.CENTER)
table.setColumnJustify(3,table.CENTER)
listId = table.addList('yes\tno\tababa\thhh') #设置list列表项,各单元之间用\t隔开
table.setColumnType(3,AFXTable.LIST) #设置第三列为列表类型
table.setColumnListId(3,listId) #在第三列添加列表
# for i in range(1,5):
# table.setColumnEditable(i,False) #设置表格列不可编辑
# table.shadeReadOnlyItems(True) #将表格设置灰度显示
setltemSpan(row, column, numRows, numColumns)函数中,row和column分别代表起始行和列的索引号,numRows 和 numColumns分别代表需要合并的行和列数。
3.4 设置表格背景及字体颜色
用户可以通过setItemTextColor()和 setItemBackColor()函数设置固定单元格的字体和背景颜色,可以通过setSelTextColor()和 setSelBackColor()函数设置鼠标/键盘所选择的单元格字体和背景颜色。颜色可以通过颜色名或者RGB值两种方式定义,具体的颜色名及对应的RGB值。
四、带表格的插件实例
开发一个如图所示的插件,该实例是一个以表格控件为主的简单材料查询插件,可以实现对常用铝合金材料力学性能的快速检索。
该插件程序代码中包含了以下功能实例:
- (1)表格控件创建及指令关联
- (2) 本地文本文件读取
- (3)表格属性控制
- (4)表格数据升序/降序排列
- (5)表格内容查询
- (6)按钮控件的创建及指令关联
包含的文件:
【materialcheckstandardDB.py】代码
#!/usr/bin/python
#-*-coding: UTF-8-*-
#-*-coding: mbcs -*-
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 materialcheckstandardDB(AFXDataDialog):
[ID_TABLE,ID_CHECK,ID_LASTONE,ID_NEXTONE]=range(AFXForm.ID_LAST, AFXForm.ID_LAST+4)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, form):
# Construct the base class.
#
FXMAPFUNC(self, SEL_CLICKED, self.ID_TABLE,
materialcheckstandardDB.onClickTable)
AFXDataDialog.__init__(self, form, '常用金属材料力学性能查询软件',
self.CANCEL, DIALOG_ACTIONS_SEPARATOR)
# okBtn = self.getActionButton(self.ID_CLICKED_OK)
# okBtn.setText('OK')
#
#
# applyBtn = self.getActionButton(self.ID_CLICKED_APPLY)
# applyBtn.setText('Apply')
#
cancelBtn = self.getActionButton(self.ID_CLICKED_CANCEL )
cancelBtn.setText('关闭')
GroupBox_1 = FXGroupBox(p=self, text='', opts=FRAME_GROOVE)
vf = FXVerticalFrame(GroupBox_1, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X,
0,0,0,0, 0,0,0,0)
# Note: Set the selector to indicate that this widget should not be
# colored differently from its parent when the 'Color layout managers'
# button is checked in the RSG Dialog Builder dialog.
vf.setSelector(99)
#设置材料数据库文件
thisPath = os.path.abspath(__file__)
thisDir = os.path.dirname(thisPath)
filename= os.path.join(thisDir, 'material_database.dat')
f=file(filename,'r')
k=0
while True:
line=f.readline()
k+=1
if len(line)==0:
break
self.num=k #定义表格的总行数
self.table = AFXTable(vf, 16, 8, k, 8, self,self.ID_TABLE, AFXTABLE_EDITABLE|LAYOUT_FILL_X)
self.table.setPopupOptions(AFXTable.POPUP_COPY|AFXTable.POPUP_WRITE_TO_FILE)
self.table.setLeadingRows(1)
self.table.setLeadingColumns(1)
self.table.setColumnWidth(1, 200)
self.table.setColumnType(1, AFXTable.TEXT)
self.table.setColumnWidth(2, 70)
self.table.setColumnType(2, AFXTable.FLOAT)
self.table.setColumnWidth(3, 70)
self.table.setColumnType(3, AFXTable.FLOAT)
self.table.setColumnWidth(4, 70)
self.table.setColumnType(4, AFXTable.FLOAT)
self.table.setColumnWidth(5, 70)
self.table.setColumnType(5, AFXTable.FLOAT)
self.table.setColumnWidth(6, 70)
self.table.setColumnType(6, AFXTable.FLOAT)
self.table.setColumnWidth(7, 70)
self.table.setColumnType(7, AFXTable.FLOAT)
self.table.setLeadingRowLabels('材料牌号 密度\n(kg/m^3) 模量\n(Mpa) 泊松比 屈服强度\n(Mpa) 极限强度\n(Mpa) 伸长率(%)')
self.table.setStretchableColumn( self.table.getNumColumns()-1 )
self.table.showHorizontalGrid(True)
self.table.showVerticalGrid(True)
self.table.setColumnSortable(1, True)
self.table.setColumnSortable(2, True)
self.table.setColumnSortable(3, True)
self.table.setColumnSortable(4, True)
self.table.setColumnSortable(5, True)
self.table.setColumnSortable(6, True)
self.table.setColumnSortable(7, True)
################################给数据库赋值
f=file(filename,'r')
k=1
while True:
line=f.readline()
if len(line)==0:
break
data=line.strip().split(',')
self.table.setItemText(k,1, data[0])
self.table.setItemText(k,2, data[1])
self.table.setItemText(k,3, data[2])
self.table.setItemText(k,4, data[3])
self.table.setItemText(k,5, data[4])
self.table.setItemText(k,6, data[5])
self.table.setItemText(k,7, data[6])
k+=1
for i in range(1,8):
self.table.setColumnEditable(i, False) #将表格设置为不可编辑
##############################
f.close()
for i in range(2,8):
self.table.setColumnJustify(i, self.table.CENTER)
HFrame_1 = FXHorizontalFrame(p=self, opts=0, x=0, y=0, w=0, h=0,
pl=0, pr=0, pt=0, pb=0)
AFXTextField(p=HFrame_1, ncols=18, labelText='输入要查询的材料名或关键字:', tgt=form.searchnameKw, sel=0)
FXButton(p=HFrame_1, text='查找', ic=None, tgt=self, sel=self.ID_CHECK)
FXMAPFUNC(self, SEL_COMMAND, self.ID_CHECK,
materialcheckstandardDB.onCmdCheck)
FXButton(p=HFrame_1, text='上一个', ic=None, tgt=self, sel=self.ID_LASTONE,x=100,y=0) #定义向前查找按钮
FXButton(p=HFrame_1, text='下一个', ic=None, tgt=self, sel=self.ID_NEXTONE,x=100,y=0) #定义向上后查找按钮
FXMAPFUNC(self, SEL_COMMAND, self.ID_LASTONE,
materialcheckstandardDB.onCmdLastone)
FXMAPFUNC(self, SEL_COMMAND, self.ID_NEXTONE,
materialcheckstandardDB.onCmdNextone)
self.form=form
self.resultnum=[]
def onClickTable(self, sender, sel, ptr): #定义排序函数
status, x, y, buttons = self.table.getCursorPosition()
column = self.table.getColumnAtX(x)
row = self.table.getRowAtY(y)
# Ignore clicks on table headers.
if row != 0 or column == 0:
return
values = []
index = 1
for row in range(1, self.table.getNumRows()):
values.append( (self.table.getItemFloatValue(
row, column), index) )
index += 1
values.sort()
if self.table.getColumnSortOrder(column) == \
AFXTable.SORT_ASCENDING:
values.reverse()
items = []
for value, index in values:
name = self.table.getItemText(index, 1)
Value2 = self.table.getItemFloatValue(index, 2)
Value3 = self.table.getItemFloatValue(index, 3)
Value4 = self.table.getItemFloatValue(index, 4)
Value5 = self.table.getItemFloatValue(index, 5)
Value6 = self.table.getItemFloatValue(index, 6)
Value7 = self.table.getItemFloatValue(index, 7)
items.append( (name, Value2, Value3,Value4,Value5,Value6,Value7,) )
row = 1
for name, Value2, Value3, Value4, Value5, Value6, Value7 in items:
self.table.setItemText(row, 1, name)
self.table.setItemFloatValue(row, 2, Value2)
self.table.setItemFloatValue(row, 3, Value3)
self.table.setItemFloatValue(row, 4, Value4)
self.table.setItemFloatValue(row, 5, Value5)
self.table.setItemFloatValue(row, 6, Value6)
self.table.setItemFloatValue(row, 7, Value7)
row += 1
def onCmdCheck(self, sender, sel, ptr):
k=1
self.table.makeRowVisible(1) #每次查找之前将表格回归到首行,可防止向前查找时所查找对象不居中显示
self.resultnum=[] #每次查找开始之前清空
NO_result=0
if self.form.searchnameKw.getValue()=='':
mw = getAFXApp().getAFXMainWindow()
mw.writeToMessageArea('请输入查询条件' )
return False
while True:
if k==self.num: #搜索到最后一行时跳出循环
break
for i in range(1,8):
self.table.setItemBackColor(k,i,FXRGB(255,255,255)) #重置颜色 FXRGB(255,255,255),"Default"
line=self.table.getItemText(k, 1)
findname=self.form.searchnameKw.getValue()
data=line.strip().split(findname)
if len(data)>1:
NO_result+=1
if NO_result==1:
self.table.setCurrentItem(k, 1) #设置第一个搜索结果为当前选择项
self.table.makeRowVisible(k+8) #使某一行结果可视 ,+8保证居中
for i in range(1,8):
self.table.setItemBackColor(k,i, 'Cyan1')
self.resultnum.append(k)
k+=1
mw = getAFXApp().getAFXMainWindow()
mw.writeToMessageArea('共查找到%i 个结果,已用特殊颜色标注。' % NO_result)
# print self.resultnum
def onCmdNextone(self, sender, sel, ptr):
curren_row_num=self.table.getCurrentRow() #返回当前选中的行
N=len(self.resultnum)
if N==0:
mw = getAFXApp().getAFXMainWindow()
mw.writeToMessageArea('还未查找到结果' )
return False
if self.resultnum[0]!=curren_row_num :
self.table.setCurrentItem(self.resultnum[0], 1)
for i in range(0,N-1):
if self.resultnum[i]==curren_row_num and self.resultnum[i]!=self.num: #保证不是最后一行
self.table.setCurrentItem(self.resultnum[i+1], 1) #设置第一个搜索结果为当前选择项
self.table.makeRowVisible(self.resultnum[i+1]) #使某一行结果可视 ,+8保证居中
for j in range(1,8):
self.table.setItemBackColor(self.resultnum[i],j, 'Cyan1') #恢复上一行原色
self.table.setItemBackColor(self.resultnum[i+1],j, 'Red') #将新的当前行着红色
# mw = getAFXApp().getAFXMainWindow()
# mw.writeToMessageArea('符合条件的结果有%i个,当前为第%i个。' % (N,i+1))
def onCmdLastone(self, sender, sel, ptr):
curren_row_num=self.table.getCurrentRow()
N=len(self.resultnum)
if N==0:
mw = getAFXApp().getAFXMainWindow()
mw.writeToMessageArea('还未查找到结果' )
return False
if self.resultnum[N-1]!=curren_row_num :
self.table.setCurrentItem(self.resultnum[N-1], 1)
for i in range(1,N):
if self.resultnum[i]==curren_row_num and self.resultnum[i]!=self.num: #保证不是最后一行
self.table.setCurrentItem(self.resultnum[i-1], 1) #设置第一个搜索结果为当前选择项
self.table.makeRowVisible(self.resultnum[i-1]) #使某一行结果可视 ,+8保证居中
for j in range(1,8):
self.table.setItemBackColor(self.resultnum[i],j, 'Cyan1') #恢复上一行原色
self.table.setItemBackColor(self.resultnum[i-1],j, 'Red') #将新的当前行着红色
# mw = getAFXApp().getAFXMainWindow()
# mw.writeToMessageArea('符合条件的结果有%i个,当前为第%i个。' % (N,i))
【materialcheckstandard_plugin.py】代码
#!/usr/bin/python
#-*-coding: UTF-8-*-
#-*-coding: mbcs -*-
from abaqusGui import *
from abaqusConstants import ALL
import osutils, os
###########################################################################
# Class definition
###########################################################################
class materialcheckstandard_plugin(AFXForm):
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def __init__(self, owner):
# Construct the base class.
#
AFXForm.__init__(self, owner)
self.radioButtonGroups = {}
self.cmd = AFXGuiCommand(mode=self, method='',
objectName='', registerQuery=False)
pickedDefault = ''
self.mattableKw = AFXTableKeyword(self.cmd, 'mattable', True)
self.mattableKw.setColumnType(0, AFXTABLE_TYPE_STRING)
self.mattableKw.setColumnType(1, AFXTABLE_TYPE_FLOAT)
self.mattableKw.setColumnType(2, AFXTABLE_TYPE_FLOAT)
self.mattableKw.setColumnType(3, AFXTABLE_TYPE_FLOAT)
self.mattableKw.setColumnType(4, AFXTABLE_TYPE_FLOAT)
self.mattableKw.setColumnType(5, AFXTABLE_TYPE_FLOAT)
self.mattableKw.setColumnType(6, AFXTABLE_TYPE_FLOAT)
self.searchnameKw = AFXStringKeyword(self.cmd, 'searchname', True, '')
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def getFirstDialog(self):
import materialcheckstandardDB
return materialcheckstandardDB.materialcheckstandardDB(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)
icon= afxCreateIcon( os.path.join(thisDir, 'findmaterial.png') )
toolset = getAFXApp().getAFXMainWindow().getPluginToolset()
toolset.registerGuiMenuButton(
buttonText='★常用金属材料力学性能查询软件',
object=materialcheckstandard_plugin(toolset),
messageId=AFXMode.ID_ACTIVATE,
icon=icon,
kernelInitString='',
applicableModules=ALL,
version='2014.5',
author='贾利勇',
description='常用金属材料的力学性能查询',
helpUrl='N/A'
)