- 积分
- 1905
- 明经币
- 个
- 注册时间
- 2022-4-4
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 枫叶棋语 于 2023-8-22 22:37 编辑
继上次的实验,我们初步实现了Ironpython环境加载Cpython环境,经过一番苦战,实现了在cad上运行Cpython,包括CAD注册命令,兼容Ipy脚本,本次更新实现了Cpython在CAD上运行,并依靠第三方模块开发的功能。相当于80%成品,因为本人能力有限,未能脱离借助Ironpython,直接使用c#调用Cpython,望后续有看到的兄弟助理一把。
这个是Cpython引擎
- import clr
- import sys
- import os
- clr.AddReference("Python.Runtime")
- clr.AddReference("acmgd")
- clr.AddReference("AcCoreMgd")
- clr.AddReference("AcDbMgd")
- clr.AddReference("System")
- import System
- import Autodesk.AutoCAD.ApplicationServices as acap
- from Python.Runtime import *
- dllpath = System.Reflection.Assembly.GetExecutingAssembly().Location
- dlldir = os.path.dirname(dllpath)
- supportdir = os.path.join(dlldir, "support")
- extensionsdir = os.path.join(dlldir, "extensions")
- referencedir = os.path.join(dlldir,"Reference")
- class CpyEngine:
- def __init__(self,pydll):
- self.pydll =pydll
- self.pyhome =os.path.dirname(pydll)
- self.pypath = "{self.pyhome}\\Lib;{self.pyhome}\\Lib\\site-packages"
- self.SetCpyEnviromnent()
- self.Initilize()
- @staticmethod
- def prinf(msg):
- acap.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(f"\n{msg}\n")
- def SetCpyEnviromnent(self):
- '''配置Cpython环境变量'''
- os.environ["PYTHONHOME"]=self.pyhome
- os.environ["PYTHONNET_PYDLL"] = self.pydll
- os.environ["PYTHONPATH"] = self.pypath
-
- def Initilize(self):
- '''初始化Cpython引擎'''
- if not PythonEngine.IsInitialized:
- PythonEngine.Initialize()
- PythonEngine.PythonPath =self.pypath
- def RunCpyScript(self,scriptpath):
- '''运行脚本'''
- import traceback
- self.scope = Py.CreateScope()
- pysys=Py.Import("sys")
- pysys.path.append(dlldir)
- pysys.path.append(supportdir)
- pysys.path.append(extensionsdir)
- pysys.path.append(referencedir)
- with open(scriptpath,"r",encoding="utf-8") as file:
- pythoncode= file.read()
- with Py.GIL():
- try:
- self.scope.Exec(pythoncode)
- except:
- error =traceback.format_exc()
- self.prinf(error)
复制代码
- import clr
- clr.AddReference("System.Windows.Forms")
- clr.AddReference("System.Drawing")
- import System
- from System.Drawing import *
- from System.Windows.Forms import *
- import os
- from pycad.system.acad import acap, prinf
- from pycad.system.CpyEngine import CpyEngine
- def check_and_create_file(filename):
- '''判断文件是否存在,不存在就创建空文件'''
- if not os.path.exists(filename):
- open(filename, 'w')
- class MainForm(Form):
- def __init__(self):
- self.InitializeComponent()
- self.Resize += self.FormChanged
- self.MinimumSize = Size(500, 500)
- self.dllpath = System.Reflection.Assembly.GetExecutingAssembly().Location
- self.dlldir = os.path.dirname(self.dllpath)
- self.history = self.dlldir+"\CpyHistory.txt"
- check_and_create_file(self.history)
- self.HistoryPaths = self.ReadHitory()
- self.ImportPaths(self.HistoryPaths)
- self.engine = CpyEngine(r"D:\Program Files\Python310\python310.dll")
- @staticmethod
- def SetButton(button,anchor, x, y, name, text, func):
- button.Anchor =anchor
- button.Location = Point(x, y)
- button.Size = Size(75, 25)
- button.Name = name
- button.Text = text
- button.UseVisualStyleBackColor = True
- button.Click += func
-
- @staticmethod
- def AddItem(listview: ListView, lst):
- item = ListViewItem(items=tuple(lst))
- listview.Items.Add(item)
-
- def InitializeComponent(self):
- self._Add = Button()
- self._Delete = Button()
- self._Clear = Button()
- self._Apply = Button()
- self._Cancel = Button()
- self._Reload = Button()
- self._ScriptPaths = ListView()
- self._FileName = ColumnHeader()
- self._FilePath = ColumnHeader()
- self.Size = Size(500, 550)
- self.ButtonWidth = 75
- self.ButtonHeight = 25
- self.ButtonX = 425
- self.ListViewWidth =self.ButtonX-75
- self.ListViewHeight =self.Size.Height -200
-
- # ScriptPaths
- self._ScriptPaths.View = View.Details
- self._ScriptPaths.Anchor = AnchorStyles.Left|AnchorStyles.Top|AnchorStyles.Bottom|AnchorStyles.Right
- self._ScriptPaths.Location = Point(30, 50)
- self._ScriptPaths.Name = "ScriptPaths"
- self._ScriptPaths.Size = Size(self.ListViewWidth,self.ListViewHeight)
- self._ScriptPaths.GridLines =True
- self._ScriptPaths.UseCompatibleStateImageBehavior = False
- self._ScriptPaths.Columns.Add("文件")
- self._ScriptPaths.Columns.Add("路径")
- self._ScriptPaths.Columns[0].Width= 150
- self._ScriptPaths.Columns[1].Width = self.ListViewWidth-150
- self._ScriptPaths.BorderStyle = BorderStyle.FixedSingle
- self._ScriptPaths.FullRowSelect =True
-
- self.SetButton(self._Add, AnchorStyles.Right| AnchorStyles.Top, 400, 70, "Add", "添加", self.AddClick)
- self.SetButton(self._Delete, AnchorStyles.Right| AnchorStyles.Top, 400, 140, "Delete", "删除", self.DeleteClick)
- self.SetButton(self._Clear, AnchorStyles.Right| AnchorStyles.Top, 400, 210, "Clear", "清空", self.ClearClick)
- self.SetButton(self._Reload, AnchorStyles.Bottom|AnchorStyles.Right,200, 450, "Reload", "重载", self.ReloadClick)
- self.SetButton(self._Apply, AnchorStyles.Bottom|AnchorStyles.Right,300, 450, "Apply", "确定", self.ApplyClick)
- self.SetButton(self._Cancel, AnchorStyles.Bottom|AnchorStyles.Right,400, 450, "Cancel", "取消", self.CancelClick)
- # 窗体添加控件
- self.Controls.Add(self._ScriptPaths)
- self.Controls.Add(self._Cancel)
- self.Controls.Add(self._Apply)
- self.Controls.Add(self._Clear)
- self.Controls.Add(self._Reload)
- self.Controls.Add(self._Delete)
- self.Controls.Add(self._Add)
- self.Text = "加载CPython脚本"
- self.ResumeLayout(False)
-
- #读取history文本内容
- def ReadHitory(self):
- with open(self.history,"r",encoding="utf-8") as file:
- existing_paths = file.read().splitlines()
- return existing_paths
- #读取listview内容
- def ReadListView(self):
- paths = []
- for item in self._ScriptPaths.Items:
- path = item.SubItems[1].Text
- paths.append(path)
- return paths
- #导入路径
- def ImportPaths(self,paths):
- for path in paths:
- basename = os.path.basename(path)
- self.AddItem(self._ScriptPaths,[basename,path])
- #导出路径
- def ExportPaths(self,paths):
- with open(self.history, "w") as file:
- for item in self._ScriptPaths.Items:
- path = item.SubItems[1].Text
- if path not in existing_paths:
- file.write(path + '\n')
- def AddClick(self, sender, e):
- openFileDialog = OpenFileDialog()
- openFileDialog.Multiselect = True
- if openFileDialog.ShowDialog() == DialogResult.OK:
- self._ScriptPaths.Items.Clear()
- file_names = openFileDialog.FileNames
- result = set(file_names)|set(self.HistoryPaths)
- self.ImportPaths(result)
- self.HistoryPaths =list(result)
- for path in file_names:
- self.engine.RunCpyScript(path)
-
- def DeleteClick(self, sender, e):
- selected_items = self._ScriptPaths.SelectedItems
- for item in selected_items:
- self._ScriptPaths.Items.Remove(item)
- self.HistoryPaths =self.ReadListView()
- def ClearClick(self, sender, e):
- self._ScriptPaths.Items.Clear()
- self.HistoryPaths = []
-
- def ApplyClick(self, sender, e):
- with open(self.history, "w") as file:
- for path in self.HistoryPaths:
- file.write(f"{path}\n")
- self.Close()
-
- def ReloadClick(self, sender, e):
- selected_items = self._ScriptPaths.SelectedItems
- for item in selected_items:
- path = item.SubItems[1].Text
- self.engine.RunCpyScript(path)
-
- def CancelClick(self, sender, e):
- self.Close()
- def FormChanged(self, sender, e):
- self._ScriptPaths.Columns[1].Width = self.Size.Width - 200
-
- loadform = MainForm()
- acap.Application.ShowModelessDialog(loadform)
与此同时,我们建立一个CpyReload脚本,用于命令重载所有脚本命令,代码如下:
- from pycad.system import prinf
- from pycad.system.CpyEngine import CpyEngine
- import System
- import os,traceback
- import re
- def check_and_create_file(filename):
- '''判断文件是否存在,不存在就创建空文件'''
- if not os.path.exists(filename):
- open(filename, 'w')
- class Reload:
- def __init__(self):
- self.engine = CpyEngine(r"D:\Program Files\Python310\python310.dll")
- self.dllpath = System.Reflection.Assembly.GetExecutingAssembly().Location
- self.dlldir = os.path.dirname(self.dllpath)
- self.history = self.dlldir+"\CpyHistory.txt"
- check_and_create_file(self.history)
- self.reload()
- def reload(self):
- with open(self.history,"r",encoding="utf-8") as file:
- paths = file.read().splitlines()
- for path in paths:
- self.engine.RunCpyScript(path)
- Reload()
复制代码 至此,CpyCAD的框架的python代码基本搭设完成,由于权限问题,暂时不能上传文件。有需要的可以联系。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
|