先说原理,Vlisp中可以通过(vlax-get-or-create-object obstr)这种形式调用一个已注册的Com对象,而在CPython中,利用pythoncom和win32com这两个模块则可以轻松地创建和注册一个Com server,以供lisp调用。lisp调用python建立的com接口时,可以直接把通过(vlax-get-acad-object)获取到的CAD接口通过传递参数的形式直接传给Python。Python一旦接收到了这个接口,能做的可就太多了。可以像vba一样访问CAD对象下所有的属性、事件和方法,甚至可以直接把这个接口存成一个文件,以便其他程序和进程来访问……
先说在Python中定义com server的方法。
import pythoncom import win32com.client as win32 import win32timezone#不导入此,无法编译为exe from win32com.client import Dispatch class PythonUtilities: _reg_clsctx_ =pythoncom.CLSCTX_LOCAL_SERVER _public_methods_=['SplitString']###外部调动的方法 _reg_progid_='PythonDemos.Utilities' # 先使用print (pythoncom.CreateGuid())" 得到一个自己的clsid,不要用下面这个!! _reg_clsid_='{848B2AEB-0E17-45E1-8D8A-0A242D4607E8}' def SplitString(self,val):####方法定义 retvalue=do_something()###编写业务代码 return retvalue ####返回值 if __name__=='__main__':####自动注册server print ('Registering COMserver...') import win32com.server.register win32com.server.register.UseCommandLine(PythonUtilities)
以上代码就定义了一个包含一个SplitString方法的com接口,运行这段代码,即可自动注册com server,如需取消注册,直接在命令行运行这个py文件,并带—unregister参数即可(无需在python源代码中写相关逻辑代码)。之后在Vlisp中运行以下代码,即可调用SplitString方法: (defun c:tt2() (setq aa (vlax-get-or-create-object "PythonDemos.Utilities")) (setq ab (vlax-invoke aa 'SplitString )) )
在windows系统上,可以把python代码通过pyinstaller编译成exe文件,在lisp中需要调用时,先执行一遍exe,在运行上述代码即可。执行exe时可选择不显示黑框,那么在用户看来,这与直接使用纯lisp插件并无区别。
下面直接给出一个案例源代码,先运行py文件再用lisp调用即可。在实际操作中,运行py文件的代码也可一并写入lisp中。本案例中python需要先安装pysimplegui模块。
以下为运行效果 :
利用这种技术思路还以制作非模态对话框,就像Lisp自带的一样无缝嵌入:
除此之外,还可以注册cad的事件,但是经过测试,凡是涉及到数据库修改的事件,用python注册之后都会引起cad崩溃(cad2014)
但是这个方法有一个致命弱点:那就是com server在win10上极难注册成功,考虑到win10普及度如此之广,可以说是相当难办了。希望能有高手提出简单易行的解决方案。
|