[UG 二次开发 PYTHON] 添加螺纹规格
NX 1988 系列 在添加螺纹特征时,不能自定义螺纹规格,
从网上找到的资料上讲,改一个XML文件,在文件中添加自定义的螺纹规格,从而实现需要的效果。
自己写了一个小程序,方便手动添加螺纹规格。
效果图
上代码
# nx: threaded
from typing import List
import os
from bs4 import BeautifulSoup as bs
import bs4
from PySide6 import QtCore as qc
from PySide6 import QtWidgets as qw
from PySide6 import QtGui as qg
os.chdir(os.path.dirname(os.path.abspath(__file__)))
r_path = ""
w_path = ""
class mw(qw.QDialog):
def __init__(self) -> None:
super().__init__()
self.ly_main = qw.QHBoxLayout(self)
"""主框架"""
self.ly_left = qw.QHBoxLayout()
"""左 主 框架"""
self.ly_left_up = qw.QVBoxLayout()
"""左 上 框架"""
self.ly_left_down = qw.QVBoxLayout()
"""左 下 框架"""
self.ly_mid = qw.QVBoxLayout()
"""中 主 框架"""
self.ly_right = qw.QVBoxLayout()
"""右 主 框架"""
self.ly_left_down.addLayout(self.ly_left_up, 0)
self.ly_left_down.addLayout(self.ly_left, 1)
self.lb_show = qw.QLabel("start")
self.ly_left_up.addWidget(self.lb_show, 1)
self.static_lb_1 = qw.QLabel("Unit")
self.cb_unit = qw.QComboBox(self)
self.cb_unit.addItems(["Metric", "Inch"])
self.cb_unit.currentIndexChanged.connect(self.on_cb_unit_change)
self.ly_left_up.addWidget(self.static_lb_1, 1)
self.ly_left_up.addWidget(self.cb_unit, 1)
self.static_lb_2 = qw.QLabel("Standard")
self.cb_standard = qw.QComboBox(self)
self.cb_standard.currentIndexChanged.connect(self.on_cb_standard_change)
self.ly_left_up.addWidget(self.static_lb_2, 1)
self.ly_left_up.addWidget(self.cb_standard, 1)
self.static_lb_3 = qw.QLabel("Size")
self.cb_size = qw.QComboBox(self)
self.cb_size.currentIndexChanged.connect(self.on_cb_size_change)
self.ly_left_up.addWidget(self.static_lb_3, 1)
self.ly_left_up.addWidget(self.cb_size, 1)
self.lb_show_name = qw.QLabel("")
self.ly_left_up.addWidget(self.lb_show_name, 1)
self.mm = qw.QLineEdit()
self.pp = qw.QLineEdit()
self.bt_copy = qw.QPushButton("复制")
self.bt_insert = qw.QPushButton("插入")
self.bt_save = qw.QPushButton("保存")
self.bt_edit = qw.QPushButton("修改")
self.bt_copy.clicked.connect(self.on_bt_copy_click)
self.bt_insert.clicked.connect(self.on_bt_insert_click)
self.bt_save.clicked.connect(self.on_bt_save_click)
self.bt_edit.clicked.connect(self.on_bt_edit_click)
self.ly_left_up.addWidget(self.bt_copy)
self.ly_left_up.addWidget(qw.QLabel("螺径"))
self.ly_left_up.addWidget(self.mm)
self.ly_left_up.addWidget(qw.QLabel("螺距"))
self.ly_left_up.addWidget(self.pp)
self.ly_left_up.addWidget(self.bt_edit)
self.ly_left_up.addWidget(self.bt_insert)
self.ly_left_up.addWidget(self.bt_save)
self.tb_mid = qw.QTableWidget(40, 2, self)
self.tb_mid.setHorizontalHeaderLabels(["属性", "值"])
self.ly_mid.addWidget(qw.QLabel("原始数据"))
self.ly_mid.addWidget(self.tb_mid)
self.tb_right = qw.QTableWidget(40, 2, self)
self.tb_right.setHorizontalHeaderLabels(["属性", "值"])
self.ly_right.addWidget(qw.QLabel("修改数据"))
self.ly_right.addWidget(self.tb_right)
self.scrollbar_mid = self.tb_mid.verticalScrollBar()
self.scrollbar_right = self.tb_right.verticalScrollBar()
self.scrollbar_mid.valueChanged.connect(self.on_tb_mid_scroll)
self.scrollbar_right.valueChanged.connect(self.on_tb_right_scroll)
self.setLayout(self.ly_main)
self.ly_main.addLayout(self.ly_left_down)
self.ly_main.addLayout(self.ly_mid)
self.ly_main.addLayout(self.ly_right)
self.resize(900, 600)
x = thread_xml_reader()
r = x.read_xml(r_path)
rot = next(r.children)
nds2 = []
for i in rot.children:
if isinstance(i, bs4.element.NavigableString) and len(str(i).strip()) == 0:
pass
else:
nds2.append(i)
self.rt = hole_root(nds2)
self.tgs: List[bs4.element.Tag] = []
self.crt = 0
self.cb_size_lst = []
self._crt_unit = ""
self._crt_standard = ""
self.crt_unit = "Metric"
self.crt_data: bs4.element.Tag = None
self.copyed_tg: bs4.element.Tag = None
self.crt = 0
@property
def crt(self):
"""当前序号"""
return self._crt
@crt.setter
def crt(self, value):
self._crt = value
if self._crt < 0:
self.lb_show_name.setText("start")
elif self._crt >= len(self.tgs):
self.lb_show_name.setText("over")
else:
self.lb_show_name.setText(f"current: {self._crt}, next =>")
self.cb_size.setCurrentIndex(self._crt)
if self._crt >= len(self.tgs):
self.tb_mid.clearContents()
self.lb_show_name.setText("")
self.lb_show.setText("over")
else:
tg = self.tgs[self._crt]
attrs = tg.attrs
self.lb_show_name.setText(tg.name)
self.lb_show.setText(f"当前 {self._crt} next->")
i = 0
for k, v in attrs.items():
item = qw.QTableWidgetItem(str(k))
self.tb_mid.setItem(i, 0, item)
item = qw.QTableWidgetItem(f"{str(v)}")
self.tb_mid.setItem(i, 1, item)
i += 1
self.crt_data = tg
@property
def crt_unit(self) -> str:
"""当前的系列 Metric Inch"""
return self._crt_unit
@crt_unit.setter
def crt_unit(self, value):
if value == self._crt_unit:
pass
else:
self._crt_unit = value
self.cb_standard.clear()
if value == "Metric":
rr = self.rt.metric
elif value == "Inch":
rr = self.rt.inch
else:
return
self.cb_size_lst = rr.ssnames
self.cb_standard.addItems(rr.ssnames)
@property
def crt_standard(self):
"""当前标号"""
return self._crt_standard
@crt_standard.setter
def crt_standard(self, value):
if value == self._crt_standard:
pass
else:
self._crt_standard = value
vv = self.cb_unit.currentText()
if vv == "Metric":
rr = self.rt.metric
elif vv == "Inch":
rr = self.rt.inch
vvs = self.cb_standard.currentText()
if vvs == "":
vvs = self.cb_size_lst[0]
r3: hole_standard = None
for i in rr.ss:
if i.standard == vvs:
r3 = i
break
if r3 != None:
self.tgs = r3.holes
xx = [i.attrs["Size"] for i in self.tgs]
self.cb_size.clear()
self.cb_size.addItems(xx)
self.crt = 0
def on_cb_unit_change(self):
self.crt_unit = self.cb_unit.currentText()
def on_cb_standard_change(self):
self.crt_standard = self.cb_standard.currentText()
def on_cb_size_change(self):
idx = self.cb_size.currentIndex()
if idx != self._crt:
self.crt = idx
def on_bt_copy_click(self) -> None:
attrs = self.crt_data.attrs.copy()
attrs["Standard"] = "User"
self.copyed_tg = bs4.element.Tag(
attrs=attrs, name=self.crt_data.name, can_be_empty_element=True
)
attrs = self.copyed_tg.attrs
self.toTb3()
def on_bt_insert_click(self) -> None:
ss = self.rt.metric.user.hole_sizes
if self.copyed_tg is None:
return
else:
tg_size = self.copyed_tg.attrs["Size"]
if tg_size not in ss:
self.rt.metric.user.holes.append(self.copyed_tg)
self.rt.metric.user.holes.sort(
key=lambda x: float(x.attrs["Size"][1:].split(" ")[0])
)
ss = self.rt.metric.user.hole_sizes
ct = -1
for i in range(len(ss)):
if ss[i] == tg_size:
ct = i
break
self.cb_unit.setCurrentText("Metric")
self.cb_standard.setCurrentText("User")
self.crt = ct
def on_bt_save_click(self) -> None:
if w_path != "":
with open(w_path, "w") as f:
for i in self.rt.toStr():
f.write(i)
def toTb3(self):
"""更新表3"""
if self.copyed_tg is not None:
attrs = self.copyed_tg.attrs
i = 0
for k, v in attrs.items():
item1 = qw.QTableWidgetItem(str(k))
self.tb_right.setItem(i, 0, item1)
item2 = qw.QTableWidgetItem(f"{str(v)}")
self.tb_right.setItem(i, 1, item2)
i += 1
if k == "Standard":
item2.setFlags(item2.flags() ^ qc.Qt.ItemIsEditable)
def on_bt_edit_click(self) -> None:
mmm = 0
ppp = 0
if self.copyed_tg is None:
return
tt = self.tb_right.item(1, 1).text()
if tt != "Metric":
return
try:
mmm = int(self.mm.text())
ppp = round(float(self.pp.text()), 2)
except:
pass
if mmm <= 0 or ppp <= 0:
return
self.copyed_tg.attrs["Size"] = f"M{mmm} x {ppp}"
self.copyed_tg.attrs["ScrewSize"] = f"M{mmm}"
self.copyed_tg.attrs["MajorDiameter"] = f"{mmm}"
self.copyed_tg.attrs["MinorDiameter"] = f"{round(mmm-ppp,3)}"
self.copyed_tg.attrs["TapDrillDia"] = f"{round(mmm-ppp+0.01,1)}"
self.copyed_tg.attrs["ShaftDiameter"] = f"{mmm}"
self.copyed_tg.attrs["Pitch"] = f"{ppp}"
self.copyed_tg.attrs["Callout"] = f"M{mmm}_x_{ppp}"
self.copyed_tg.attrs["HoleDepth"] = f"{mmm*2}"
self.copyed_tg.attrs["ThreadDepth"] = f"{int(mmm*1.5)}"
self.copyed_tg.attrs["ReliefDiameter"] = f"{float(mmm):0.3f}"
self.copyed_tg.attrs["ReliefDepth"] = f"{mmm*0.5:0.3f}"
self.copyed_tg.attrs["ReliefChamferOffset"] = f"{round(ppp*1.1,1):0.3f}"
self.copyed_tg.attrs["StartChamferDiameter"] = f"{float(mmm):0.3f}"
self.copyed_tg.attrs["EndChamferDiameter"] = f"{float(mmm):0.3f}"
self.toTb3()
def on_tb_mid_scroll(self, e):
self.tb_right.verticalScrollBar().setValue(e)
def on_tb_right_scroll(self, e):
self.tb_mid.verticalScrollBar().setValue(e)
class thread_xml_reader:
def __init__(self) -> None:
pass
def read_xml(self, rpath: str):
if os.path.exists(rpath):
with open(rpath, "r", encoding="utf8") as f:
soup = bs(f, "lxml-xml")
return soup
class hole_root:
def __init__(self, hs: List[bs4.element.Tag]) -> None:
met = []
icht = []
for i in hs:
if i.attrs["Unit"] == "Metric":
met.append(i)
elif i.attrs["Unit"] == "Inch":
icht.append(i)
self.metric = hole_metric(met)
self.inch = hole_inch(icht)
def toStr(self):
yield """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n"""
#yield "<root>\n"
yield "<Root>\n"
for i in self.inch.ss:
for k in i.holes:
kas = k.attrs
r = " <" + k.name
for k, v in kas.items():
r += f' {k}="{v}"'
r += " />\n"
yield r
for i in self.metric.ss:
for k in i.holes:
kas = k.attrs
r = " <" + k.name
for k, v in kas.items():
r += f' {k}="{v}"'
r += " />\n"
yield r
#yield "</root>"
yield "</Root>"
class hole_metric:
"""Metric"""
unit = "Metric"
def __init__(self, hs: List[bs4.element.Tag]) -> None:
rr = {}
nn = []
for i in hs:
s = i.attrs["Standard"]
if s in nn:
rr[s].append(i)
else:
nn.append(s)
rr[s] = [i]
self.ss: List[hole_standard] = [hole_standard(k, v) for k, v in rr.items()]
for i in self.ss:
if i.standard == "User":
self.user = i
break
else:
self.user = hole_standard("User", [])
self.ss.append(self.user)
@property
def ssnames(self):
return [i.standard for i in self.ss]
class hole_inch:
"""Inch"""
unit = "Inch"
def __init__(self, hs: List[bs4.element.Tag]) -> None:
rr = {}
nn = []
for i in hs:
s = i.attrs["Standard"]
if s in nn:
rr[s].append(i)
else:
nn.append(s)
rr[s] = [i]
self.ss = [hole_standard(k, v) for k, v in rr.items()]
@property
def ssnames(self):
return [i.standard for i in self.ss]
class hole_standard:
"standard"
def __init__(self, name: str, hs: List[bs4.element.Tag]) -> None:
self.standard = name
self.holes = hs
@property
def hole_sizes(self) -> List[str]:
return [i.attrs["Size"] for i in self.holes]
def main():
app = qw.QApplication()
mm = mw()
mm.show()
app.exec()
exit()
if __name__ == "__main__":
ug_base_dir = os.getenv("UGII_BASE_DIR")
if ug_base_dir is None or ug_base_dir == "":
pass
else:
file_dir = os.path.join(ug_base_dir, "UGII", "modeling_standards")
w_path = r_path = os.path.join(file_dir, "NX_Thread_Standard.xml")
backup_path = os.path.join(file_dir, "NX_Thread_Standard_bak.xml")
if not os.path.exists(r_path):
raise FileNotFoundError(r_path)
if not os.path.exists(backup_path):
import shutil
shutil.copy(r_path, backup_path)
main()
没有写删除的功能,怕不小心误操作,要删除某一个规格的话,自己打开 相应的XML文件,手动删除行就行了
22.06.11
输出时的,root 更正为 Root .... 低级错误
[UG 二次开发 PYTHON] 添加螺纹规格的更多相关文章
- Openstack Murano(kilo)二次开发之添加Volume
Openstack Murano(kilo)二次开发之添加Volume 欢迎转载,转载请注明出处:http://www.cnblogs.com/fmnisme/p/openstack_murano_a ...
- TFS二次开发系列:四、TFS二次开发WorkItem添加和修改、保存
WorkItemStore:表示跟踪与运行 Team Foundation Server的服务器的工作项客户端连接. A.添加工作项 1.首先获得某服务器的WorkItemStore. WorkIte ...
- 【转】Jenkins 二次开发 - Python
马克,备用: Jenkins 二次开发 https://testerhome.com/topics/14988?locale=zh-TW python-jenkins api 文档:https://p ...
- UG二次开发-CAM-获取修改路径参数
项目中要获取路径参数,网上大多是C++的例子,而本项目是用C#写的,探索了下,记录下. 以获取某条路径的刀具号为例,其他参数依此类推. using System; using System.Colle ...
- phpcms v9 二次开发 - 自己添加源文件
一.在根目录添加入口文件, 我现在要在根目录添加一个文件名为test.php 这样一个文件,为了调用系统的公用类和函数,必须加入一下包含文件 test.php代码如下 <?phpdefine(' ...
- 基于ZFAKA二次开发,添加PayJS支付渠道
项目地址:https://github.com/hiyouli/payjs-for-zfaka 关于ZFAKA,请移步:ZFAKA 免费.安全.稳定.高效的发卡系统,值得拥有! 演示地址:http:/ ...
- Revit二次开发之添加选项卡和按钮
我们日常在revit开发中经常会用到按钮,可以通过revitAPI提供的接口创建按钮,今天我简单介绍一下两种按钮,一种是单命令按钮,另一种是含下拉菜单的按钮,包括创建他们的方法. 实现方法 1.实 ...
- UG二次开发-CAM-执行方式
以C#开发为例,通常先用[操作记录]功能录制关键代码,得到一个.cs文件. (1)可以直接使用[播放操作记录]的方式执行该.cs文件. (2)可以建立一个C#的类库工程,将上述.cs文件加载进去,添加 ...
- Ubuntu环境下Nutch1.2 二次开发(添加中文分词)
前提nutch1.2已部署到eclipse中 详见:http://www.cnblogs.com/cy163/archive/2013/02/19/2916419.html 1 部署IKAnalyze ...
- NX二次开发-自定义添加右键菜单RegisterConfigureContextMenuCallback
首先声明这个知识我以前不知道,是夏天的时候看到别人在唐工的QQ群里问的,唐工说西门子官方有这个例子.那个时候我因为在忙其他事情,也就没去研究那个右键菜单到底是怎么做的.关于自定义添加右键菜单Regis ...
随机推荐
- Dash 2.17版本新特性介绍
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/dash-master 大家好我是费老师,不久前Dash发布了其2.17.0版本,执行下面的命令进行最 ...
- Docker基础 ubuntu安装docker
目录 如何在Linux深度系统deepin下安装docker 介绍 安装docker 在ubuntu的docker中运行ubuntu 在ubuntu的docker中运行centos 卸载docker ...
- nim 1. 安装、IDE、HelloWorld
2015年,某大神写过nim的教程,请参阅: Nim教程[一] - liulun - 博客园 (cnblogs.com) 七年过去了, nim应该更成熟了. 1.安装 下载页面:Windows ins ...
- C语言:水仙花
//水仙花数 也就是指一个 3 位数,它的每个单位上的数字的 3次方之和等于它本身 (例如:1^3 + 5^3+ 3^3 = 153). #include<stdio.h> int mai ...
- 14个Flink SQL性能优化实践分享
本文分享自华为云社区<Flink SQL性能优化实践> ,作者:超梦. 在大数据处理领域,Apache Flink以其流处理和批处理一体化的能力,成为许多企业的首选.然而,随着数据量的增长 ...
- 【C#】使用WebHttpRequest调用Restful带token接口500 返回401 未授权错误
测试对方的接口,发现单个调用对方接口是可以的,但是多个连续的调用对方接口时,会出现第一条调用一般是200,随后的调用就会报500,401未授权的错误,除了第一条后面的请求数据几乎都不得行. 我于是用f ...
- MFC之ListControl选中行删除
if (m_list.GetSelectedCount() > 0) { POSITION pos= m_list.GetFirstSelectedItemPosition(); while ( ...
- objectarx acedInitGet的使用
int rc;TCHAR keyword[20]; acedInitGet(NULL, TEXT("U Y O"));rc = acedGetPoint(ptPre, L" ...
- 【已解决】docker overlay2占用大量磁盘空间处理方法
在使用docker容器的时候遇到了容量上的问题,做一个记录 处理方式1:在使用docker时,往往会出现磁盘空间不足,导致该问题的通常原因是因为docker中部署的系统输出了大量的日志内容. 此时,可 ...
- C++笔记(4)友元
通常情况下,公有类方法是访问类对象私有部分的唯一途径.除此之外,C++还提供了另外一种形式的访问权限:友元. 友元有三种: 友元函数 友元类 友元成员函数 通过让函数成为类的友元,可以赋予该函数与类的 ...