Abaqus GUI程序开发之常用控件使用方法(二十六):表格控件AFXTable使用方法

这个表格内容比较多,之前一直有些逃避,现在学完了其他控件,决定回来补一下。

一、创建表格控件

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'
)

 

 文件下载icon-default.png?t=L9C2https://wws.lanzoui.com/ieKDyvjygoj

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是刃小木啦~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值