python操作CAD,文本批量提取

  • A+
所屬分類:cad

運(yùn)行代碼后界面

python操作CAD,文本批量提取代碼如下:

import sys
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
                             QLabel, QLineEdit, QPushButton, QProgressBar, QFileDialog,
                             QMessageBox, QGroupBox)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QFont, QIcon
import pyautocad
from openpyxl import Workbook

class CadExtractorThread(QThread):
    progress_signal = pyqtSignal(int, str)
    finished_signal = pyqtSignal(bool, str)
   
    def __init__(self, folder_path, excel_path):
        super().__init__()
        self.folder_path = folder_path
        self.excel_path = excel_path
        self.running = True
        
    def run(self):
        try:
            # 連接到AutoCAD
            acad = pyautocad.Autocad()
            
            if not acad.app:
                self.finished_signal.emit(False, "無(wú)法連接到AutoCAD,請(qǐng)確保AutoCAD正在運(yùn)行")
                return
            
            # 創(chuàng)建Excel工作簿
            wb = Workbook()
            ws = wb.active
            ws.title = "CAD文本匯總"
            ws.append(["文件名", "序號(hào)", "文本內(nèi)容", "X坐標(biāo)", "Y坐標(biāo)", "Z坐標(biāo)"])
            
            total_count = 0
            processed_files = 0
            dwg_files = [f for f in os.listdir(self.folder_path) if f.lower().endswith('.dwg')]
            total_files = len(dwg_files)
            
            for filename in dwg_files:
                if not self.running:
                    break
                    
                filepath = os.path.join(self.folder_path, filename)
                file_count = 0
               
                try:
                    # 打開(kāi)CAD文件
                    doc = acad.app.Documents.Open(filepath)
                    self.progress_signal.emit(processed_files * 100 // total_files, f"正在處理: {filename}")
                    
                    # 設(shè)置當(dāng)前文檔
                    acad.doc = doc
                    
                    # 遍歷當(dāng)前文檔中的文本對(duì)象
                    for obj in acad.iter_objects(['Text', 'MText']):
                        try:
                            total_count += 1
                            file_count += 1
                            text_content = obj.TextString
                            insertion_point = obj.InsertionPoint
                           
                            ws.append([
                                filename,
                                file_count,
                                text_content,
                                insertion_point[0],
                                insertion_point[1],
                                insertion_point[2] if len(insertion_point) > 2 else 0,
                            ])
                           
                        except Exception as e:
                            continue
                    
                    # 關(guān)閉當(dāng)前文檔
                    doc.Close(False)
                    processed_files += 1
                    
                except Exception as e:
                    continue
            
            # 保存Excel文件
            if self.running:
                wb.save(self.excel_path)
                self.finished_signal.emit(True, f"成功處理 {processed_files}/{total_files} 個(gè)文件\n提取 {total_count} 個(gè)文本對(duì)象")
            else:
                self.finished_signal.emit(False, "操作已取消")
               
        except Exception as e:
            self.finished_signal.emit(False, f"發(fā)生錯(cuò)誤: {str(e)}")
            
    def stop(self):
        self.running = False

class CadTextExtractorUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("CAD文本提取工具")
        self.setGeometry(100, 100, 600, 400)
        self.setWindowIcon(QIcon("cad_icon.png"))  # 替換為您自己的圖標(biāo)或刪除此行
        
        # 初始化線程
        self.extractor_thread = None
        
        # 設(shè)置主窗口樣式
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f5f5f5;
            }
            QGroupBox {
                border: 1px solid #ccc;
                border-radius: 5px;
                margin-top: 10px;
                padding-top: 15px;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 3px;
            }
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 8px 16px;
                text-align: center;
                text-decoration: none;
                font-size: 14px;
                margin: 4px 2px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:disabled {
                background-color: #cccccc;
            }
            QPushButton#cancel_button {
                background-color: #f44336;
            }
            QPushButton#cancel_button:hover {
                background-color: #d32f2f;
            }
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            QProgressBar {
                border: 1px solid #ccc;
                border-radius: 4px;
                text-align: center;
            }
            QProgressBar::chunk {
                background-color: #4CAF50;
                width: 10px;
            }
        """)
        
        self.init_ui()
        
    def init_ui(self):
        main_widget = QWidget()
        main_layout = QVBoxLayout()
        
        # 標(biāo)題
        title_label = QLabel("CAD文本批量提取工具")
        title_label.setFont(QFont("Arial", 16, QFont.Bold))
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet("color: blue; margin-bottom: 5px;")
        main_layout.addWidget(title_label)

        #title_label = QLabel("authour: 摸魚 | VX: Lee-three-nine")
        #title_label.setFont(QFont("微軟", 12))
        #title_label.setAlignment(Qt.AlignCenter)
        #title_label.setStyleSheet("color: #333; margin-bottom: 5px;")
        #main_layout.addWidget(title_label)


        # 輸入組
        input_group = QGroupBox("文件設(shè)置")
        input_layout = QVBoxLayout()
        
        # CAD文件夾選擇
        cad_folder_layout = QHBoxLayout()
        cad_folder_label = QLabel("CAD文件夾:")
        self.cad_folder_edit = QLineEdit()
        self.cad_folder_edit.setPlaceholderText("請(qǐng)選擇包含DWG文件的文件夾")
        cad_folder_button = QPushButton("瀏覽...")
        cad_folder_button.clicked.connect(self.select_cad_folder)
        cad_folder_layout.addWidget(cad_folder_label)
        cad_folder_layout.addWidget(self.cad_folder_edit)
        cad_folder_layout.addWidget(cad_folder_button)
        input_layout.addLayout(cad_folder_layout)
        
        # Excel保存路徑
        excel_layout = QHBoxLayout()
        excel_label = QLabel("保存路徑:")
        self.excel_edit = QLineEdit()
        self.excel_edit.setPlaceholderText("請(qǐng)選擇Excel文件保存位置")
        excel_button = QPushButton("瀏覽...")
        excel_button.clicked.connect(self.select_excel_path)
        excel_layout.addWidget(excel_label)
        excel_layout.addWidget(self.excel_edit)
        excel_layout.addWidget(excel_button)
        input_layout.addLayout(excel_layout)
        
        input_group.setLayout(input_layout)
        main_layout.addWidget(input_group)
        
        # 進(jìn)度組
        progress_group = QGroupBox("提取進(jìn)度")
        progress_layout = QVBoxLayout()
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        progress_layout.addWidget(self.progress_bar)
        
        self.status_label = QLabel("準(zhǔn)備就緒")
        self.status_label.setAlignment(Qt.AlignCenter)
        progress_layout.addWidget(self.status_label)
        
        progress_group.setLayout(progress_layout)
        main_layout.addWidget(progress_group)
        
        # 按鈕組
        button_layout = QHBoxLayout()
        
        self.start_button = QPushButton("開(kāi)始提取")
        self.start_button.clicked.connect(self.start_extraction)
        button_layout.addWidget(self.start_button)
        
        self.cancel_button = QPushButton("取消")
        self.cancel_button.setObjectName("cancel_button")
        self.cancel_button.clicked.connect(self.cancel_extraction)
        self.cancel_button.setEnabled(False)
        button_layout.addWidget(self.cancel_button)
        
        main_layout.addLayout(button_layout)
        
        main_widget.setLayout(main_layout)
        self.setCentralWidget(main_widget)
        
    def select_cad_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "選擇CAD文件夾")
        if folder:
            self.cad_folder_edit.setText(folder)
            
    def select_excel_path(self):
        path, _ = QFileDialog.getSaveFileName(self, "保存Excel文件", "", "Excel文件 (*.xlsx)")
        if path:
            if not path.endswith('.xlsx'):
                path += '.xlsx'
            self.excel_edit.setText(path)
            
    def start_extraction(self):
        cad_folder = self.cad_folder_edit.text()
        excel_path = self.excel_edit.text()
        
        if not cad_folder or not excel_path:
            QMessageBox.warning(self, "警告", "請(qǐng)先選擇CAD文件夾和Excel保存路徑")
            return
            
        if not os.path.isdir(cad_folder):
            QMessageBox.warning(self, "警告", "CAD文件夾路徑無(wú)效")
            return
            
        # 檢查文件夾中是否有DWG文件
        has_dwg = any(f.lower().endswith('.dwg') for f in os.listdir(cad_folder))
        if not has_dwg:
            QMessageBox.warning(self, "警告", "選擇的文件夾中沒(méi)有DWG文件")
            return
            
        # 禁用按鈕
        self.start_button.setEnabled(False)
        self.cancel_button.setEnabled(True)
        
        # 重置進(jìn)度
        self.progress_bar.setValue(0)
        self.status_label.setText("正在初始化...")
        
        # 創(chuàng)建并啟動(dòng)提取線程
        self.extractor_thread = CadExtractorThread(cad_folder, excel_path)
        self.extractor_thread.progress_signal.connect(self.update_progress)
        self.extractor_thread.finished_signal.connect(self.extraction_finished)
        self.extractor_thread.start()
        
    def cancel_extraction(self):
        if self.extractor_thread and self.extractor_thread.isRunning():
            self.extractor_thread.stop()
            self.status_label.setText("正在取消操作...")
            
    def update_progress(self, progress, message):
        self.progress_bar.setValue(progress)
        self.status_label.setText(message)
        
    def extraction_finished(self, success, message):
        self.start_button.setEnabled(True)
        self.cancel_button.setEnabled(False)
        
        if success:
            self.progress_bar.setValue(100)
            QMessageBox.information(self, "完成", message)
        else:
            QMessageBox.warning(self, "警告", message)
            
        self.status_label.setText("操作完成" if success else "操作失敗")
        
    def closeEvent(self, event):
        if self.extractor_thread and self.extractor_thread.isRunning():
            reply = QMessageBox.question(self, '確認(rèn)退出',
                                       '提取過(guò)程仍在進(jìn)行中,確定要退出嗎?',
                                       QMessageBox.Yes | QMessageBox.No,
                                       QMessageBox.No)
            
            if reply == QMessageBox.Yes:
                self.extractor_thread.stop()
                self.extractor_thread.wait()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()

if __name__ == "__main__":
    app = QApplication(sys.argv)
   
    # 設(shè)置應(yīng)用程序樣式#設(shè)計(jì)學(xué)徒自學(xué)網(wǎng)www.sx1c.com
    app.setStyle('Fusion')
   
    window = CadTextExtractorUI()
    window.show()
    sys.exit(app.exec_())

 

歷史上的今天:

推薦應(yīng)用

發(fā)表評(píng)論

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: