当前位置 : 主页 > 编程语言 > 其它开发 >

[UG 二次开发 PYTHON] 添加螺纹规格

来源:互联网 收集:自由互联 发布时间:2022-06-09
NX 1988 系列 在添加螺纹特征时,不能自定义螺纹规格, 从网上找到的资料上讲,改一个XML文件,在文件中添加自定义的螺纹规格,从而实现需要的效果。 自己写了一个小程序,方便手
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"
        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>"


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文件,手动删除行就行了 【本文转自:韩国cn2服务器 http://www.558idc.com/kt.html欢迎留下您的宝贵建议】
上一篇:从普通双非到百度算法岗,优秀!
下一篇:没有了
网友评论