Python SolidWorks 二次开发—SolidWorks插件(addin)的实现,增加SolidWorks菜单项
文章目录
前言
上次我们用Python实现了创建属性页的功能,这次我们用python实现插件功能,在SolidWorks工具中的插件都需要加载dll来实现,Python无法直接实现生成dll的功能,但是也可以实现插件的功能,这里就简单演示一个用Python实现的菜单项,并点击菜单项能实现相应的功能,实现过程其实是类似属性页面的创建的,只是略有不同,依然是在SolidWorks2022上测试完成的。友情提醒下,要实现商业插件的,不建议用Python通过COM实现,因为COM实现的过程有很多坑。
第一步,创建com接口
Python创建com接口其实非常简单,以下为一个简单是示例
- reg_clsid 是随机生成的
- reg_progid 是自己定义的名称
- public_methods 是需要公开的方法
其中_reg_clsid_ 可以使用print(pythoncom.CreateGuid())随机生成。
将以下代码拷贝到PropertyManagerPageHandler.py文件中,直接运行后就完成了com的注册,注册时需要管理员身份,否则后期可能无法调用。注册执行一次就可以了,后面可直接修改此文件即可,不用重复注册。
#SldAddin.py
# 创建com接口
class SldAddin:
_public_methods_ = ["testfun"]
_reg_clsid_ = "{F155709E-EAB4-4EA5-9B41-479702905241}"
_reg_progid_ = "mycom.sldaddin"
def testfun(self,arg):
print('com测试')
print(f'com测试,{arg}')
if __name__=="__main__":
# 注册接口
import win32com.server.register
win32com.server.register.UseCommandLine(SldAddin)
第二步,com接口测试
新建main.py文件,拷贝以下代码后,运行,即可在终端看到运行后的结果。
pagehandler=win32com.client.Dispatch("mycom.SldAddin")
pagehandler.testfun('我是第一个参数')
运行以上代码终端显示的结果,可以看到com的函数已经成功运行,并传递了参数,实现了我们想要的结果
第三步,关联com接口和属性页
上面第二步只是测试了接口是否正常,接力来将逐步实现属性的各项功能,先删除main.py中的代码,将以下代码拷贝到main.py中
#main.py
import win32com.client
import pythoncom
def main():
# SolidWorks年份版本
sldver=2022
# 建立com连接,如只有一个版本,可以只写"SldWorks.Application"
swApp=win32com.client.Dispatch(f'SldWorks.Application.{sldver-1992}')
# 提升API交互效率
swApp.CommandInProgress =True
# swApp.SendMsgToUser('就是我被点击了')
# 显示SolidWorks界面
swApp.Visible =True
# 获取接口对象
sldaddin=win32com.client.Dispatch('mycom.sldaddin')
# 给插件设置接口
res=swApp.SetAddinCallbackInfo2(0, sldaddin, 1)
# 获取插件
iCmdMgr = swApp.GetCommandManager(1)
errors=win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, -1)
# 创建菜单
cmdGroup = iCmdMgr.CreateCommandGroup2(1, "python插件", "", "", -1,True,errors)
# 创建子菜单
cmdIndex0 = cmdGroup.AddCommandItem2("第一个命令",
-1,"","",0, "hellosld", "", 0, 1)
# 显示菜单
cmdGroup.Activate
while True:
pythoncom.PumpWaitingMessages()
if __name__=="__main__":
main()
第四步,显示属性页
运行第三步中的代码,将会在SolidWorks中看到在工具菜单下增加了python插件菜单,此时点击第一个命令不会有任何效果
第五步,修改SldAddin.py
将第一步创建的SldAddin.py文件内容修改如下,注意,这里要再以管理员身份运行下此文件,主要是为了注册ISwAddin接口
#SldAddin.py
from win32com import universal
universal.RegisterInterfaces("{C71C31CD-898C-11D4-AEF6-00C04F603FAF}", 0, 30,0, ["ISwAddin"])
# 创建com接口
class SldAddin:
_com_interfaces_ = ["ISwAddin"]
_public_methods_ = []
_reg_clsid_ = "{F155709E-EAB4-4EA5-9B41-479702905241}"
_reg_progid_ = "mycom.sldaddin"
if __name__=="__main__":
# # 注册接口
import win32com.server.register
win32com.server.register.UseCommandLine(SldAddin)
第六步,继续修改SldAddin.py
增加两个函数,一个是用来接受当前运行的swapp的,一个是实现"第一个命令"的函数
#SldAddin.py
def getswapp(self,swapp):
self.swapp=swapp
def hellosld(self):
self.swapp.SendMsgToUser('hello solidworks')
同时将以上两个函数添加到_public_methods_中去
#SldAddin.py
_public_methods_ = ['getswapp','hellosld']
第七步,修改main.py
主要增加getswapp函数的调用,将swapp对象传递给com,这里要注意下第六步定义的hellosld函数的名称其实是来自 cmdGroup.AddCommandItem2(“第一个命令”,-1,“”,“”,0, “hellosld”, “”, 0, 1)中的,一定要和第六个参数名称一致,参数的详细说明可以看API帮助文档。
#main.py
sldaddin.getswapp(swApp)
第八步,查看运行结果
设置完成后再次运行,点击第四步出现的第一个命令,就会弹出以下的对话框,内容就是第六步定义的内容。
注:如果运行后报错"AttributeError: ‘PyIDispatch’ object has no attribute ‘SendMsgToUser’",则将第六步定义的函数修改下,修改后的代码如下,这个错误之前的文章也都说过如何解决,另外不是每个版本都会报错:
#SldAddin.py
def getswapp(self,swapp):
self.swapp=win32com.client.Dispatch(swapp)
总结:至此用Python创建的SolidWorks插件(addin)的实现,增加SolidWorks菜单项就完成了,可以在此基础上增加自己想要的功能。以下为两个文件的源码。
- PropertyManagerPageHandler.py文件源码
#SldAddin.py
from win32com import universal
import win32com.client
universal.RegisterInterfaces("{C71C31CD-898C-11D4-AEF6-00C04F603FAF}", 0, 30,0, ["ISwAddin"])
# 创建com接口
class SldAddin:
_com_interfaces_ = ["ISwAddin"]
_public_methods_ = ['getswapp','hellosld']
_reg_clsid_ = "{F155709E-EAB4-4EA5-9B41-479702905241}"
_reg_progid_ = "mycom.sldaddin"
def getswapp(self,swapp):
self.swapp=win32com.client.Dispatch(swapp)
def hellosld(self):
self.swapp.SendMsgToUser('hello solidworks')
if __name__=="__main__":
# # 注册接口
import win32com.server.register
win32com.server.register.UseCommandLine(SldAddin)
- main.py文件源码
#main.py
import win32com.client
import pythoncom
from swconst import constants
def main():
# SolidWorks年份版本
sldver=2022
# 建立com连接,如只有一个版本,可以只写"SldWorks.Application"
swApp=win32com.client.Dispatch(f'SldWorks.Application.{sldver-1992}')
# 提升API交互效率
swApp.CommandInProgress =True
# swApp.SendMsgToUser('就是我被点击了')
# 显示SolidWorks界面
swApp.Visible =True
# 获取接口对象
sldaddin=win32com.client.Dispatch('mycom.sldaddin')
sldaddin.getswapp(swApp)
# 给插件设置接口
res=swApp.SetAddinCallbackInfo2(0, sldaddin, 1)
# 获取插件
iCmdMgr = swApp.GetCommandManager(1)
errors=win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, -1)
# 创建菜单
cmdGroup = iCmdMgr.CreateCommandGroup2(1, "python插件", "", "", -1,True,errors)
# 创建子菜单
cmdIndex0 = cmdGroup.AddCommandItem2("第一个命令",
-1,"","",0, "hellosld", "", 0, 1)
# 显示菜单
cmdGroup.Activate
while True:
pythoncom.PumpWaitingMessages()
if __name__=="__main__":
main()