Python3.7+PyQt5 pyuic5将.ui文件转换为.py文件、Python读取配置文件、生成日志

1.实际开发项目时,是使用Qt Designer来设计UI界面,得到一个.ui的文件,然后利用PyQt5安装时自带的工具pyuic5将.ui文件转换为.py文件:

pyuic5 -o mywindow.py mywindow.ui #先是py文件名,再是ui文件名

样式图 QT5 UI:

转换的pyqt5:

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'ActionTools.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
import socketfrom PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
import sys
import io
import os
import datetime
import random
from subprocess import Popen,PIPE
from threading import Thread
import time
import configparserclass Ui_ActionWinfrm(QWidget):def __init__(self):super(Ui_ActionWinfrm,self).__init__()self.config=configparser.ConfigParser()#创建对象self.EmployeeInfo=[]#员工信息self.TestServer=[]#测试服务器设置self.MesServer=[]#Mes服务器self.ProductInfo=[]#产品信息self.config.read("./conf/config.conf",encoding="utf-8")#读取配置文件,如果配置文件不存在创建self.Err="NULL"#员工管理信息self.EmployeeInfo.append(self.config.get('EmployeeInfo','Employee'))#工号self.EmployeeInfo.append(self.config.get('EmployeeInfo','Line'))#线体#测试服务器设置self.TestServer.append(self.config.get('TestServer','host'))self.TestServer.append(self.config.get('TestServer','prot'))self.TestServer.append(self.config.get('TestServer','user'))self.TestServer.append(self.config.get('TestServer','password'))#连接服务器self.host = self.TestServer[0]self.prot = self.TestServer[1]#MES服务器设置self.MesServer.append(self.config.get('MesServer','url'))#产品信息self.ProductInfo.append(self.config.get('ProductInfo','ClientName'))self.ProductInfo.append(self.config.get('ProductInfo','ProductName'))self.ProductInfo.append(self.config.get('ProductInfo','OrderInfo'))self.ProductInfo.append(self.config.get('ProductInfo','OrderTotal'))self.ProductInfo.append(self.config.get('ProductInfo','CompleteOrder'))self.data=''self.setupUi()print(self.host + "," + self.prot)self.Client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)def setupUi(self):self.setObjectName("ActionWinfrm")self.resize(1000, 943)font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(12)self.setFont(font)icon = QtGui.QIcon()icon.addPixmap(QtGui.QPixmap("./Imag/020.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.setWindowIcon(icon)self.verticalLayout = QtWidgets.QVBoxLayout(self)self.verticalLayout.setObjectName("verticalLayout")self.frame_5 = QtWidgets.QFrame(self)self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)self.frame_5.setObjectName("frame_5")self.frame_6 = QtWidgets.QFrame(self.frame_5)self.frame_6.setGeometry(QtCore.QRect(0, -1, 981, 41))self.frame_6.setStyleSheet("color: rgb(85, 255, 127);")self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)self.frame_6.setObjectName("frame_6")self.lbl_WinTitle = QtWidgets.QLabel(self.frame_6)self.lbl_WinTitle.setGeometry(QtCore.QRect(390, 0, 351, 41))font = QtGui.QFont()font.setPointSize(26)self.lbl_WinTitle.setFont(font)self.lbl_WinTitle.setAlignment(QtCore.Qt.AlignCenter)self.lbl_WinTitle.setObjectName("lbl_WinTitle")self.lbl_loginfo = QtWidgets.QLabel(self.frame_6)self.lbl_loginfo.setGeometry(QtCore.QRect(10, 0, 161, 41))self.lbl_loginfo.setText("")self.lbl_loginfo.setPixmap(QtGui.QPixmap("./Imag/logo.jpg"))self.lbl_loginfo.setObjectName("lbl_loginfo")self.frame_7 = QtWidgets.QFrame(self.frame_5)self.frame_7.setGeometry(QtCore.QRect(0, 50, 981, 80))self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)self.frame_7.setObjectName("frame_7")self.label = QtWidgets.QLabel(self.frame_7)self.label.setGeometry(QtCore.QRect(10, 10, 81, 16))self.label.setAlignment(QtCore.Qt.AlignCenter)self.label.setObjectName("label")self.label_3 = QtWidgets.QLabel(self.frame_7)self.label_3.setGeometry(QtCore.QRect(340, 10, 81, 16))self.label_3.setAlignment(QtCore.Qt.AlignCenter)self.label_3.setObjectName("label_3")self.label_4 = QtWidgets.QLabel(self.frame_7)self.label_4.setGeometry(QtCore.QRect(660, 10, 81, 16))self.label_4.setAlignment(QtCore.Qt.AlignCenter)self.label_4.setObjectName("label_4")self.label_2 = QtWidgets.QLabel(self.frame_7)self.label_2.setGeometry(QtCore.QRect(10, 50, 81, 16))self.label_2.setAlignment(QtCore.Qt.AlignCenter)self.label_2.setObjectName("label_2")self.label_5 = QtWidgets.QLabel(self.frame_7)self.label_5.setGeometry(QtCore.QRect(340, 50, 81, 16))self.label_5.setAlignment(QtCore.Qt.AlignCenter)self.label_5.setObjectName("label_5")self.label_6 = QtWidgets.QLabel(self.frame_7)self.label_6.setGeometry(QtCore.QRect(660, 50, 81, 16))self.label_6.setAlignment(QtCore.Qt.AlignCenter)self.label_6.setObjectName("label_6")self.label_7 = QtWidgets.QLabel(self.frame_7)self.label_7.setGeometry(QtCore.QRect(820, 50, 91, 20))self.label_7.setAlignment(QtCore.Qt.AlignCenter)self.label_7.setObjectName("label_7")self.lbl_ClientName = QtWidgets.QLabel(self.frame_7)self.lbl_ClientName.setGeometry(QtCore.QRect(100, 10, 151, 16))self.lbl_ClientName.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_ClientName.setObjectName("lbl_ClientName")self.lbl_ProductName = QtWidgets.QLabel(self.frame_7)self.lbl_ProductName.setGeometry(QtCore.QRect(420, 10, 54, 12))self.lbl_ProductName.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_ProductName.setObjectName("lbl_ProductName")self.lbl_OrderInfo = QtWidgets.QLabel(self.frame_7)self.lbl_OrderInfo.setGeometry(QtCore.QRect(730, 10, 101, 16))self.lbl_OrderInfo.setAutoFillBackground(False)self.lbl_OrderInfo.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_OrderInfo.setObjectName("lbl_OrderInfo")self.lbl_Employee = QtWidgets.QLabel(self.frame_7)self.lbl_Employee.setGeometry(QtCore.QRect(90, 50, 91, 16))self.lbl_Employee.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_Employee.setObjectName("lbl_Employee")self.lbl_Line = QtWidgets.QLabel(self.frame_7)self.lbl_Line.setGeometry(QtCore.QRect(420, 50, 81, 16))self.lbl_Line.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_Line.setObjectName("lbl_Line")self.lbl_OrderTotal = QtWidgets.QLabel(self.frame_7)self.lbl_OrderTotal.setGeometry(QtCore.QRect(730, 50, 54, 12))self.lbl_OrderTotal.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_OrderTotal.setObjectName("lbl_OrderTotal")self.lbl_COrderNum = QtWidgets.QLabel(self.frame_7)self.lbl_COrderNum.setGeometry(QtCore.QRect(910, 50, 54, 19))self.lbl_COrderNum.setStyleSheet("color: rgb(255, 170, 0);")self.lbl_COrderNum.setObjectName("lbl_COrderNum")self.textEdit = QtWidgets.QTextEdit(self.frame_5)self.textEdit.setGeometry(QtCore.QRect(0, 40, 981, 1))self.textEdit.setObjectName("textEdit")self.TW_TestItemList = QtWidgets.QTableWidget(self.frame_5)self.TW_TestItemList.setGeometry(QtCore.QRect(0, 180, 981, 631))font = QtGui.QFont()font.setPointSize(12)self.TW_TestItemList.setFont(font)self.TW_TestItemList.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)self.TW_TestItemList.setShowGrid(False)self.TW_TestItemList.setObjectName("TW_TestItemList")self.TW_TestItemList.setColumnCount(3)self.TW_TestItemList.setRowCount(0)self.item = QtWidgets.QTableWidgetItem()self.item.setTextAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(12)self.item.setFont(font)icon1 = QtGui.QIcon()icon1.addPixmap(QtGui.QPixmap("Imag/NewAdd.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.item.setIcon(icon1)self.TW_TestItemList.setHorizontalHeaderItem(0, self.item)self.item = QtWidgets.QTableWidgetItem()self.item.setTextAlignment(QtCore.Qt.AlignCenter)font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(12)self.item.setFont(font)icon2 = QtGui.QIcon()icon2.addPixmap(QtGui.QPixmap("Imag/TestArgs.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.item.setIcon(icon2)self.TW_TestItemList.setHorizontalHeaderItem(1, self.item)self.item = QtWidgets.QTableWidgetItem()self.item.setTextAlignment(QtCore.Qt.AlignCenter)font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(12)self.item.setFont(font)icon3 = QtGui.QIcon()icon3.addPixmap(QtGui.QPixmap("Imag/Result.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.item.setIcon(icon3)self.TW_TestItemList.setHorizontalHeaderItem(2, self.item)self.TW_TestItemList.horizontalHeader().setMinimumSectionSize(40)self.TW_TestItemList.verticalHeader().setDefaultSectionSize(50)self.TW_TestItemList.verticalHeader().setMinimumSectionSize(50)self.label_8 = QtWidgets.QLabel(self.frame_5)self.label_8.setGeometry(QtCore.QRect(10, 140, 112, 25))self.label_8.setObjectName("label_8")self.lbl_TestResult = QtWidgets.QLabel(self.frame_5)self.lbl_TestResult.setGeometry(QtCore.QRect(0, 815, 981, 111))self.lbl_TestResult.setStyleSheet("background-color: rgb(0, 0, 0);\n""font: 22pt \"Arial\";\n""color: rgb(255, 255, 0);")self.lbl_TestResult.setAlignment(QtCore.Qt.AlignCenter)self.lbl_TestResult.setObjectName("lbl_TestResult")self.lbl_Isn = QtWidgets.QLineEdit(self.frame_5)self.lbl_Isn.setGeometry(QtCore.QRect(130, 140, 800, 31))self.lbl_Isn.setObjectName("lbl_Isn")self.verticalLayout.addWidget(self.frame_5)self.retranslateUi()QtCore.QMetaObject.connectSlotsByName(self)self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowCloseButtonHint)  # 只显示最小化按钮和关闭按钮self.lbl_Isn.setFocus()def retranslateUi(self):self._translate = QtCore.QCoreApplication.translateself.setWindowTitle(self._translate("ActionWinfrm", "【T.e.s.t】"))self.lbl_WinTitle.setText(self._translate("ActionWinfrm", "国产系统在线激活工具"))self.label.setText(self._translate("ActionWinfrm", "客户名称:"))self.label_3.setText(self._translate("ActionWinfrm", "产品名称:"))self.label_4.setText(self._translate("ActionWinfrm", "订单号:"))self.label_2.setText(self._translate("ActionWinfrm", "员工工号:"))self.label_5.setText(self._translate("ActionWinfrm", "线          体:"))self.label_6.setText(self._translate("ActionWinfrm", "订单数:"))self.label_7.setText(self._translate("ActionWinfrm", "完成订单数:"))self.lbl_ClientName.setText(self.ProductInfo[0])#客户名称self.lbl_ProductName.setText(self.ProductInfo[1])#产品名称self.lbl_OrderInfo.setText(self.ProductInfo[2])#订单信息self.lbl_OrderTotal.setText(self.ProductInfo[3])#订单总数self.lbl_COrderNum.setText(self.ProductInfo[4])#完成订单数self.lbl_Employee.setText(self.EmployeeInfo[0])#工号self.lbl_Line.setText(self.EmployeeInfo[1])#线体self.item = self.TW_TestItemList.horizontalHeaderItem(0)self.item.setText(self._translate("ActionWinfrm", "项目名称"))self.item = self.TW_TestItemList.horizontalHeaderItem(1)self.item.setText(self._translate("ActionWinfrm", "测试参数"))self.item = self.TW_TestItemList.horizontalHeaderItem(2)self.item.setText(self._translate("ActionWinfrm", "测试结果"))self.TW_TestItemList.setColumnWidth(0,300)self.TW_TestItemList.setColumnWidth(1, 370)self.TW_TestItemList.setColumnWidth(2, 300)self.TW_TestItemList.setShowGrid(False)#是否显示网线self.label_8.setText(self._translate("ActionWinfrm", "扫描整机条码:"))self.lbl_TestResult.setText(self._translate("ActionWinfrm", "待测试"))def Center(self):#定义一个函数使得函数窗口居中显示#获取屏幕坐标系self.screen=QDesktopWidget().screenGeometry()#获取窗口坐标系self.size=self.geometry()self.newLeft=(self.screen.width()-self.size.width())/2self.newTop=(self.screen.height()-self.size.height())/2.7self.move(int(self.newLeft),int(self.newTop))def Connect(self,message):try:self.Client_socket.connect(self.host,int(self.port))self.lbl_TestResult.setText("Connected To Server..")self.lbl_TestResult.setForeground(QtGui.QColor(51, 204, 51))self.Client_socket.sendall(message.encode())self.data=self.Client_socket.recv(1024)except Exception as e:self.lbl_TestResult.setText("Connected To Server Err:"+str(e))self.lbl_TestResult.setStyleSheet("color:red")return Falseself.Client_socket.close()return Trueif __name__ == '__main__':app = QApplication(sys.argv)win = Ui_ActionWinfrm()win.Center()win.show()#win.Client('10.2.230.10', 8888)win.Connect('tell me the product name and position:00E04C060621')sys.exit(app.exec_())

效果:

2.Python学习之读取配置文件:

初始配置文件test.conf:

步骤1:导入配置文件模块

import configparser

步骤2:创建配置文件对象

config = configparser.ConfigParser()

步骤3:读取配置文件
在这一步中,我们将读取配置文件。配置文件通常存储在.ini或.conf文件中。

config.read('config.ini')

步骤4:获取配置选项

option_value = config.get('section_name', 'option_name')

步骤5:修改配置选项

config.set('section_name', 'option_name', 'new_value')

步骤6:保存配置文件

with open('config.ini', 'w') as config_file:config.write(config_file)

*.展正读取confg的实列:

3.生成日志:

1.创建日志记录器

import logging# 创建一个日志记录器实例
logger = logging.getLogger('my_logger')

2 设置日志记录级别

logger.setLevel(logging.DEBUG)使用setLevel()方法设置日志记录的级别,可以根据需要进行调整。常用的日志级别有:logging.DEBUG:最详细的日志信息,用于调试程序。
logging.INFO:一般的日志信息,用于确认程序正常运行。
logging.WARNING:警告信息,表明程序可能出现问题。
logging.ERROR:错误信息,程序出现错误但仍然可以继续运行。
logging.CRITICAL:严重错误信息,程序无法继续运行。

3.创建文件处理器

file_handler = logging.FileHandler('log.txt')

4.设置文件处理器的格式

formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)

5.将处理器添加到记录器中

logger.addHandler(file_handler)

6.输出日志信息

logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/150196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单链表相关面试题--1.删除链表中等于给定值 val 的所有节点

/* 解题思路:从头节点开始进行元素删除,每删除一个元素,需要重新链接节点 */ struct ListNode* removeElements(struct ListNode* head, int val) {if(head NULL)return NULL;struct ListNode* cur head;struct ListNode* prev NULL;while…

vulnhub靶机Presidential

靶机地址:https://download.vulnhub.com/presidential/Presidential.ova 主机发现 arp-scan -l 端口扫描 nmap --min-rate 10000 192.168.21.150 端口服务扫描 nmap -sV -sT -O -p80 192.168.21.150 漏洞扫描 nmap --scriptvuln -p80 192.168.21.150 只有一个端…

海康Visionmaster-环境配置:MFC 二次开发环境配置方法

1 新建 MFC 工程,拷贝 DLL:VM\VisionMaster4.0.0\Development\V4.0.0 \ComControl\bin\x64 下的所有拷贝到项目工程输出目录下,如下图所示,项目的输出路径是 Dll 文件夹。 2 通过配置 C目录和链接器的方式配置 VM 环境 2.1 C目录下添加附加…

【开源】基于JAVA的校园失物招领管理系统

项目编号: S 006 ,文末获取源码。 \color{red}{项目编号:S006,文末获取源码。} 项目编号:S006,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 招领管理模块2.2 寻物管理模块2.3 系…

用对了吗?正确打开文件传输助手的方式

在这个高速发展的信息时代,我们每天都会面临一个重要的问题:如何在手机和电脑之间快速、高效地传输文件? 有时候,我们需要把工作中的一份报告从电脑传到手机,以便在路上查看;有时候,我们又想把手…

【Qt之QStandardItemModel】使用,tableview、listview、treeview设置模型

1. 引入 QStandardItemModel类提供了一个通用的模型,用于存储自定义数据。 以下是其用法:该类属于gui模块,因此在.pro中,需添加QT gui,如果已存在,则无需重复添加。 首先,引入头文件&#xff…

AI实践与学习1_Milvus向量数据库实践与原理分析

前言 随着NLP预训练模型(大模型)以及多模态研究领域的发展,向量数据库被使用的越来越多。 在XOP亿级题库业务背景下,对于试题召回搜索单单靠着ES集群已经出现性能瓶颈,因此需要预研其他技术方案提高试题搜索召回率。…

【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV4)模型算法详解

【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV4)模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV4)模型算法详解前言GoogLeNet(InceptionV4)讲解Stem结构Inception-A结构Inception- B结构Inception-C结构redution-A结构re…

宽瞬时带宽放大器SKY66051-11、SKY66052-11、SKY66041-11、SKY66317-11(RF)适用于通讯网络

一、2300至2700 MHz宽瞬时带宽高增益线性驱动放大器:SKY66051-11 SKY66051-11是一款具有高增益和高线性度的宽瞬时带宽、完全输入/输出匹配驱动放大器。通过使用外部元件,增益可在30dB至36dB范围内调整。紧凑型33 mm PA专为工作频率为2300至2700 MHz的4…

Skywalking流程分析_9(JDK类库中增强流程)

前言 之前的文章详细介绍了关于非JDK类库的静态方法、构造方法、实例方法的增强拦截流程,本文会详细分析JDK类库中的类是如何被增强拦截的 回到最开始的SkyWalkingAgent#premain try {/** 里面有个重点逻辑 把一些类注入到Boostrap类加载器中 为了解决Bootstrap类…

开源与闭源:大模型时代的技术交融与商业平衡

一、开源和闭源的优劣势比较 1.1 开源 优势: 1.技术共享与吸引人才: 开源促进了技术共享,吸引了全球范围内的人才参与大模型的发展,形成了庞大的开发者社区。 2.推动创新: 开源模式鼓励开发者共同参与,推动…

uni-app:如何配置uni.request请求的超时响应时间(全局+局部)

方法一:全局配置响应时间 一、进入项目的manifest.json的代码视图模块 二、写入代码 "networkTimeout": {"request": 5000 }, 表示现在request请求响应时间最多位5秒 方法二:局部设置响应时间 一、直接在uni.request中写入属性…

微服务下整合knife4j接口文档

前言:本文旨在解决微服务下通过网关访问所用服务的knife4j文档,无需再通过其他服务单独访问 功能模块配置: 1.配置类: 在这个文件中注意下basePackage的扫描路径,修改为对应controller下的路径。 Configuration EnableSwagger…

打造自己的3D模型AI 自动纹理工具

在线工具推荐: 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 为 3D 模型创建纹理可能比您想象的要容易。虽然注意细节很重要,但有很多方法可以制…

超详细~25考研规划~感恩现在努力的你!!!

25考研规划 俄语,翻译过来叫我爱你 考试时间 第一天 8.30-11.30政治——100分 2.00-5.00英语——100分 第二天 8.30-11.30数学——150分 2.00-5.00专业课——150分 1.什么是25考研 将在2024年12月参加考研,2025年本科毕业,9月读研究…

java基础练习缺少项目?看这篇文章就够了(下)!

公众号:全干开发 。 专注分享简洁但高质量的动图技术文章! 回顾 在上节内容中,我们实现了用户开户的功能createAccount public void start(){System.out.println("欢迎您进入到了ATM系统");System.out.println("1、用户登录&…

git基本用法和操作

文章目录 创建版本库方式:Git常用操作命令:远程仓库相关命令分支(branch)操作相关命令版本(tag)操作相关命令子模块(submodule)相关操作命令忽略一些文件、文件夹不提交其他常用命令 创建版本库方式: 创建文件夹 在目录下 右键 Git Bush H…

如何使用$APPEALS法,分析用户期待?

$APPEALS分析法是一种用于分析用户期待和需求的方法,它可以帮助企业全方位多角度地了解客户对产品的期望,有助于企业多维度有侧重地调整市场规划和产品改进策略,帮助企业打造优势产品,提高市场竞争力。 下面是使用$APPEALS分析法来…

键盘控制ROS车运动

键盘控制ROS车运动 上位机 使用pyseria库与stm32单片机进行通信控制 #!/usr/bin/env python # -*- coding: utf-8 -*import sys, select, termios, tty import serialmsg """ ---------------------------w a x ds w : x a : y s : -x …

广西柳州机械异形零部件三维扫描3D抄数全尺寸测绘建模-CASAIM中科广电

一、背景介绍 复杂机械异形零部件具有不规则的形状和复杂的结构,给生产制造带来了很大的检测难度。为了确保零部件的制造质量和精度,需要对零部件进行全面的尺寸检测和分析。 CASAIM三维扫描仪在机械异形零部件全尺寸检测应用可以实现对机械异形零部件…