import sysimport globimport osfrom os import path as ospimport timefrom PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox, QLabel, QLineEdit, QPushButton, QSpinBox, QTextEdit, QMessageBox, QFileDialog, QComboBox)from PyQt6.QtCore import Qt, QThreadPoolfrom PyQt6.QtGui import QFontclass CADMergeMainWindow(QMainWindow): """主窗口""" def __init__(self): super().__init__() self.init_ui() self.setup_styles() def init_ui(self): self.setWindowTitle("CAD图纸合并工具(欢迎关注微信公众号:码海听潮)") self.setMinimumSize(700, 620) self.setFixedSize(700, 620) # 中央部件 central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) main_layout.setSpacing(10) main_layout.setContentsMargins(15, 15, 15, 15) # 参数设置区域 param_group = QGroupBox("参数设置") param_group.setObjectName("paramGroup") param_layout = QGridLayout(param_group) param_layout.setSpacing(8) param_layout.setContentsMargins(12, 15, 12, 12) # 路径选择 param_layout.addWidget(QLabel("工作目录:"), 0, 0) self.path_edit = QLineEdit() self.path_edit.setPlaceholderText("选择包含DWG文件的目录...") self.path_edit.setReadOnly(True) self.path_edit.setMaximumHeight(28) param_layout.addWidget(self.path_edit, 0, 1) self.browse_btn = QPushButton("浏览") self.browse_btn.setObjectName("browseBtn") self.browse_btn.setMaximumHeight(28) self.browse_btn.clicked.connect(self.browse_folder) param_layout.addWidget(self.browse_btn, 0, 2) # CAD版本选择 param_layout.addWidget(QLabel("CAD版本:"), 1, 0) self.cad_version_combo = QComboBox() self.cad_version_combo.setMaximumHeight(28) self.cad_version_combo.addItems([ "ZWCAD.Application.2017", "ZWCAD.Application.2018", "ZWCAD.Application.2019", "ZWCAD.Application.2020", "ZWCAD.Application.2021", "ZWCAD.Application.2022", "ZWCAD.Application.2023", "ZWCAD.Application.2024", "ZWCAD.Application.2025", "ZWCAD.Application.2026" ]) self.cad_version_combo.setEditable(True) param_layout.addWidget(self.cad_version_combo, 1, 1) # 参数输入 param_layout.addWidget(QLabel("分组间距 (d):"), 2, 0) self.d_spin = QSpinBox() self.d_spin.setRange(0, 10000) self.d_spin.setValue(50) self.d_spin.setMaximumHeight(28) param_layout.addWidget(self.d_spin, 2, 1) param_layout.addWidget(QLabel("上下间距 (t):"), 3, 0) self.t_spin = QSpinBox() self.t_spin.setRange(0, 10000) self.t_spin.setValue(100) self.t_spin.setMaximumHeight(28) param_layout.addWidget(self.t_spin, 3, 1) param_layout.addWidget(QLabel("基点 X:"), 4, 0) self.base_x_spin = QSpinBox() self.base_x_spin.setRange(0, 100000) self.base_x_spin.setValue(5000) self.base_x_spin.setMaximumHeight(28) param_layout.addWidget(self.base_x_spin, 4, 1) param_layout.addWidget(QLabel("基点 Y:"), 5, 0) self.base_y_spin = QSpinBox() self.base_y_spin.setRange(0, 100000) self.base_y_spin.setValue(5000) self.base_y_spin.setMaximumHeight(28) param_layout.addWidget(self.base_y_spin, 5, 1) param_layout.setColumnStretch(1, 1) main_layout.addWidget(param_group) # 控制按钮 btn_layout = QHBoxLayout() btn_layout.setSpacing(10) self.start_btn = QPushButton("开始合并") self.start_btn.setObjectName("startBtn") self.start_btn.clicked.connect(self.start_merge) self.start_btn.setMaximumHeight(36) self.stop_btn = QPushButton("停止") self.stop_btn.setObjectName("stopBtn") self.stop_btn.clicked.connect(self.stop_merge) self.stop_btn.setEnabled(False) self.stop_btn.setMaximumHeight(36) btn_layout.addStretch() btn_layout.addWidget(self.start_btn) btn_layout.addWidget(self.stop_btn) btn_layout.addStretch() main_layout.addLayout(btn_layout) # 日志区域 log_group = QGroupBox("处理日志") log_group.setObjectName("logGroup") log_layout = QVBoxLayout(log_group) log_layout.setSpacing(5) log_layout.setContentsMargins(10, 12, 10, 10) self.log_text = QTextEdit() self.log_text.setReadOnly(True) self.log_text.setObjectName("logText") self.log_text.setFont(QFont("Consolas", 9)) self.log_text.setMaximumHeight(300) log_layout.addWidget(self.log_text) main_layout.addWidget(log_group) # 初始化线程池 self.threadpool = QThreadPool() self.threadpool.setMaxThreadCount(1) def setup_styles(self): """设置样式表""" style = """ QMainWindow { background-color: #f0f2f5; } QGroupBox { font-size: 12px; font-weight: bold; font-family: "Microsoft YaHei"; border: 2px solid #d0d7e2; border-radius: 8px; margin-top: 10px; padding-top: 10px; background-color: white; } QGroupBox::title { subcontrol-origin: margin; left: 12px; padding: 0 8px; color: #2c3e50; }#paramGroup { background-color: white; }#logGroup { background-color: white; } QLabel { font-family: "Microsoft YaHei"; font-size: 12px; color: #2c3e50; } QLineEdit { padding: 4px 10px; border: 2px solid #d0d7e2; border-radius: 6px; font-size: 12px; background-color: #f8f9fa; } QLineEdit:focus { border-color: #667eea; } QSpinBox { padding: 4px 8px; border: 2px solid #d0d7e2; border-radius: 6px; font-size: 12px; background-color: #f8f9fa; min-height: 20px; } QSpinBox:focus { border-color: #667eea; } QComboBox { padding: 4px 8px; border: 2px solid #d0d7e2; border-radius: 6px; font-size: 12px; background-color: #f8f9fa; min-height: 20px; } QComboBox:focus { border-color: #667eea; } QComboBox::drop-down { border: none; } QComboBox::down-arrow { image: none; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 4px solid #666; margin-right: 5px; }#browseBtn { background-color: #e8ecf1; border: none; border-radius: 6px; padding: 4px 16px; font-size: 12px; font-weight: bold; font-family: "Microsoft YaHei"; color: #2c3e50; }#browseBtn:hover { background-color: #d5dbe4; }#startBtn { background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #667eea, stop:1 #764ba2); border: none; border-radius: 8px; padding: 8px 30px; font-size: 14px; font-weight: bold; font-family: "Microsoft YaHei"; color: white; min-width: 120px; }#startBtn:hover { opacity: 0.9; }#startBtn:disabled { opacity: 0.5; }#stopBtn { background-color: #e74c3c; border: none; border-radius: 8px; padding: 8px 30px; font-size: 14px; font-weight: bold; font-family: "Microsoft YaHei"; color: white; min-width: 120px; }#stopBtn:hover { background-color: #c0392b; }#stopBtn:disabled { opacity: 0.5; }#logText { background-color: #1a1a2e; color: #e0e0e0; border: none; border-radius: 6px; font-family: "Consolas"; font-size: 11px; padding: 8px; } """ self.setStyleSheet(style) def browse_folder(self): """选择文件夹""" folder = QFileDialog.getExistingDirectory( self, "选择包含DWG文件的目录", "", QFileDialog.Option.ShowDirsOnly ) if folder: self.path_edit.setText(folder) dwg_files = glob.glob(osp.join(folder, '**', '*.dwg'), recursive=True) if dwg_files: self.log(f"找到 {len(dwg_files)} 个DWG文件") else: self.log("⚠️ 该目录下未找到DWG文件") def log(self, message): """添加日志""" self.log_text.append(f"[{time.strftime('%H:%M:%S')}] {message}") scrollbar = self.log_text.verticalScrollBar() scrollbar.setValue(scrollbar.maximum()) def start_merge(self): """开始合并(界面逻辑)""" path = self.path_edit.text() if not path or not osp.exists(path): QMessageBox.warning(self, "警告", "请选择有效的工作目录!") return dwg_files = glob.glob(osp.join(path, '**', '*.dwg'), recursive=True) if not dwg_files: QMessageBox.warning(self, "警告", "指定目录下未找到DWG文件!") return reply = QMessageBox.question( self, "确认开始", f"将在目录 '{path}' 中处理 {len(dwg_files)} 个DWG文件。\n\n是否继续?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.No: return # 禁用控件 self.start_btn.setEnabled(False) self.stop_btn.setEnabled(True) self.browse_btn.setEnabled(False) self.cad_version_combo.setEnabled(False) # 清空日志 self.log_text.clear() self.log("=" * 60) self.log("🚀 开始CAD图纸合并任务") self.log(f"工作目录: {path}") self.log(f"CAD版本: {self.cad_version_combo.currentText()}") self.log(f"找到 {len(dwg_files)} 个DWG文件") self.log("=" * 60) # 获取参数 d = self.d_spin.value() t = self.t_spin.value() base_point = (self.base_x_spin.value(), self.base_y_spin.value(), 0) cad_version = self.cad_version_combo.currentText() # TODO: 这里调用实际的合并逻辑 # self.worker = CADMergeWorker(path, d, t, base_point, cad_version) # self.threadpool.start(self.worker) def stop_merge(self): """停止合并(界面逻辑)""" reply = QMessageBox.question( self, "确认停止", "确定要停止当前合并任务吗?\n\n已处理的内容将不会保存。", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.Yes: self.log("⏹ 正在停止任务...") self.stop_btn.setEnabled(False) # TODO: 调用停止逻辑def main(): app = QApplication(sys.argv) app.setWindowIcon(QIcon()) app.setApplicationName("CAD图纸合并工具") app.setOrganizationName("CAD Tools") window = CADMergeMainWindow() window.show() sys.exit(app.exec())if __name__ == "__main__": main()