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] 添加螺纹规格的更多相关文章

  1. Openstack Murano(kilo)二次开发之添加Volume

    Openstack Murano(kilo)二次开发之添加Volume 欢迎转载,转载请注明出处:http://www.cnblogs.com/fmnisme/p/openstack_murano_a ...

  2. TFS二次开发系列:四、TFS二次开发WorkItem添加和修改、保存

    WorkItemStore:表示跟踪与运行 Team Foundation Server的服务器的工作项客户端连接. A.添加工作项 1.首先获得某服务器的WorkItemStore. WorkIte ...

  3. 【转】Jenkins 二次开发 - Python

    马克,备用: Jenkins 二次开发 https://testerhome.com/topics/14988?locale=zh-TW python-jenkins api 文档:https://p ...

  4. UG二次开发-CAM-获取修改路径参数

    项目中要获取路径参数,网上大多是C++的例子,而本项目是用C#写的,探索了下,记录下. 以获取某条路径的刀具号为例,其他参数依此类推. using System; using System.Colle ...

  5. phpcms v9 二次开发 - 自己添加源文件

    一.在根目录添加入口文件, 我现在要在根目录添加一个文件名为test.php 这样一个文件,为了调用系统的公用类和函数,必须加入一下包含文件 test.php代码如下 <?phpdefine(' ...

  6. 基于ZFAKA二次开发,添加PayJS支付渠道

    项目地址:https://github.com/hiyouli/payjs-for-zfaka 关于ZFAKA,请移步:ZFAKA 免费.安全.稳定.高效的发卡系统,值得拥有! 演示地址:http:/ ...

  7. Revit二次开发之添加选项卡和按钮

      我们日常在revit开发中经常会用到按钮,可以通过revitAPI提供的接口创建按钮,今天我简单介绍一下两种按钮,一种是单命令按钮,另一种是含下拉菜单的按钮,包括创建他们的方法. 实现方法 1.实 ...

  8. UG二次开发-CAM-执行方式

    以C#开发为例,通常先用[操作记录]功能录制关键代码,得到一个.cs文件. (1)可以直接使用[播放操作记录]的方式执行该.cs文件. (2)可以建立一个C#的类库工程,将上述.cs文件加载进去,添加 ...

  9. Ubuntu环境下Nutch1.2 二次开发(添加中文分词)

    前提nutch1.2已部署到eclipse中 详见:http://www.cnblogs.com/cy163/archive/2013/02/19/2916419.html 1 部署IKAnalyze ...

  10. NX二次开发-自定义添加右键菜单RegisterConfigureContextMenuCallback

    首先声明这个知识我以前不知道,是夏天的时候看到别人在唐工的QQ群里问的,唐工说西门子官方有这个例子.那个时候我因为在忙其他事情,也就没去研究那个右键菜单到底是怎么做的.关于自定义添加右键菜单Regis ...

随机推荐

  1. kibana-6.2.4-amd64的安装

    ubuntu系统 kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D 找到6.2.4的下载连接 方法一: 下载tar包,解压即可: ...

  2. 3 个好玩的前端开源项目「GitHub 热点速览」

    单休的周末总是短暂的,还没缓过神新的一周就又开始了.如果你和我一样状态还没有完全恢复,那就让上周好玩的开源项目唤醒你吧! 每周 GitHub 上总是有一些让人眼前一亮的开源项目,上周好玩的前端项目特别 ...

  3. MindSpore梯度进阶操作

    技术背景 在MindSpore深度学习框架中,我们可以使用mindspore.grad对函数式编程的函数直接计算自动微分,也可以使用mindspore.ops.GradOperation求解Cell类 ...

  4. 复现禅道V17.4的sql注入漏洞

    漏洞详情 简述:禅道是第一款国产的开源项目管理软件,它的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理.计划管理.发布管理.文档管理.事务管理等功 ...

  5. 通过XML标记生成word

    思路 word生成可以通过标签,也可以通过XML元素. word文档实际上是由文档对象模型描述的,因此我们能够通过对文档对象进行操作去生成word. 由于word允许我们附加XML结构(元素),如下: ...

  6. vue2前端导出带背景色表格 xlsx xlsx-style

    vue2 +elmentui+xlsx10.0.0+xlsx-style 坑有点多. xlsx10.0.0以后的版本 用require导入或者使用什么导入什么,不要import * xlsx全部导入 ...

  7. 深入理解Docker原理

    本文参考转载至:<深入剖析Kubernetes - 张磊> 更过优秀博文请关注:https://blog.bigcoder.cn 容器技术的核心功能,就是通过约束和修改进程的动态表现,从而 ...

  8. jQuery——链式操作

    链式操作,即连续操作. 例如: <!DOCTYPE html> <html> <head> <script src="https://cdn.boo ...

  9. Vue——模板语法

    Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据.所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析 ...

  10. NOIP模拟87(多校20)

    前言 题目不难,但是个人感觉小细节有一些,然后有亿点卡常.. 感觉对于笛卡尔树的题目看不出算法,然后代码实现方面细节注意太少,常数有点大. 下次注意吧. T1 集合均值 解题思路 感觉应该是期望题里面 ...