当前位置:首页>python>《彻底告别逐张打印!用Python打造AutoCAD批量打印工具,效率无敌猛!》

《彻底告别逐张打印!用Python打造AutoCAD批量打印工具,效率无敌猛!》

  • 2026-08-18 23:11:40
《彻底告别逐张打印!用Python打造AutoCAD批量打印工具,效率无敌猛!》

“带你横跨办公自动化的数据江海”

@摸鱼

前言

关于摸鱼

ABOUT MOYU

闻道有先后,术业有专攻。

各位大佬朋友们好!

~我依旧是你们的老朋友摸鱼~

在职场摸爬滚打的这十多年里,我用Python悄悄干了不少“正事”——不知不觉攒下了一整套办公自动化的实用项目技巧。去年10月初创立了公众号 「码海听潮」 ,初衷很简单:把重复的劳动交给代码,把摸鱼的时间留给生活。

目前已经吭哧吭哧更新了140多篇原创文章,每一篇都是实操干货,不讲虚的,只聊怎么用代码真正解放双手,帮大家早点下班、准点摸鱼

好了,多了不说,少了不唠,今天给大佬们分享一款本人原创的【AutoCAD批量打印工具 - BatchPlot】这款工具相比手动逐张框选打印,效率提升数十倍,这是一个非常实用的CAD自动化工具,特别适合需要批量出图、多图框打印的场景。支持图块、理正图框、图层三种图框识别模式,批量打印、生成布局、打印预览三种输出方式一键切换,差异内容自动红字黄底标注,一目了然!图框自动排序、自动旋转、自动适配比例,真正做到解放双手,让批量打印变得如此简单!

《该办公工具成品展示:》

《该办公工具核心功能亮点:》

01

 亮点1:智能化图框识别

        • 三种识别模式:支持图块识别、理正图框识别、图层识别,适配不同图纸标准

        • 一键搜索:点击"选择图框"自动扫描当前图纸中的所有图框

        • 高亮显示:选中图框可在AutoCAD中高亮标记,直观确认选择范围

        02

         亮点2:灵活的打印设置🎨

            • 多种输出方式:支持直接打印到设备、打印到PLT文件、预览三种模式

            • 智能比例适配:自动计算最佳打印比例,支持"适合纸张"、"自动"、"自定义"多种比例选项

            • 自动旋转与排序:图框自动旋转适配纸张方向,支持从左到右/从上到下排序,可反向输出

            • 批量打印份数:支持设置打印份数,一次性完成多份输出

            03

            亮点3:布局批量生成⚙️

            • 一键生成布局:将多个图框自动转换为独立的布局选项卡

            • 自定义布局前缀:支持设置布局名称前缀,便于管理

            • 自动清理:可自动删除已有同前缀布局,避免重复

            《该办公工具代码展示:》

            下面,我就用python代码让各位大佬见识一下,什么叫"传统文化"遇上"赛博效率"

            """BatchPlot - AutoCAD批量打印工具 """import sysfrom typing import ListOptionalfrom dataclasses import dataclass, fieldfrom PyQt6.QtWidgets import (    QApplicationQMainWindowQWidgetQVBoxLayoutQHBoxLayout,    QGroupBoxQLabelQPushButtonQComboBoxQSpinBoxQCheckBox,    QRadioButtonQButtonGroupQTextEditQFileDialog,    QMessageBoxQLineEditQListWidgetQListWidgetItem,    QSplitterQGridLayoutQProgressBarQScrollAreaQFrame)from PyQt6.QtCore import Qtfrom PyQt6.QtGui import QFontQTextCursor@dataclassclass PlotSettings:    """打印设置"""    frame_mode: str = "BlockRadio"    block_name: str = ""    layer_name: str = ""    output_mode: str = "PlotRadio"    plot_scale: str = "Auto"    copies: int = 1    auto_rotate: bool = True    upside_down: bool = False    layout_prefix: str = "BP_"    plot_file_prefix: str = "PLOT_"    plot_file_folder: str = ""    delete_plot_file: bool = False    delete_layout: bool = False    ms_line_scale: bool = True    reverse_order: bool = False    selected_frames: List = field(default_factory=list)class MainWindow(QMainWindow):    """主窗口 - 纯界面设计"""    def __init__(self):        super().__init__()        self.settings = PlotSettings()        self.frames = []        self.init_ui()        self.setup_connections()    def init_ui(self):        """初始化UI"""        self.setWindowTitle("BatchPlot - AutoCAD批量打印工具")        self.setMinimumSize(900650)        font = QFont("Microsoft YaHei"9)        self.setFont(font)        self.setStyleSheet("""            QMainWindow { background-color: #f0f2f5; }            QGroupBox {                font-weight: bold;                border: 1px solid #d0d7de;                border-radius: 6px;                margin-top: 8px;                padding-top: 8px;                background-color: white;                font-size: 11px;            }            QGroupBox::title {                subcontrol-origin: margin;                left: 10px;                padding: 0 6px;                color: #24292f;            }            QPushButton {                background-color: #2d8cf0;                color: white;                border: none;                border-radius: 4px;                padding: 5px 12px;                font-weight: bold;                font-size: 11px;            }            QPushButton:hover { background-color: #1a7ad4; }            QPushButton:pressed { background-color: #1664b8; }            QPushButton:disabled {                background-color: #b0b8c4;                color: #8a94a0;            }            QPushButton#dangerButton { background-color: #ed4014; }            QPushButton#dangerButton:hover { background-color: #d4390f; }            QPushButton#successButton { background-color: #19be6b; }            QPushButton#successButton:hover { background-color: #16a85a; }            QPushButton#warningButton { background-color: #f7a11a; }            QPushButton#warningButton:hover { background-color: #e0910e; }            QPushButton#connectButton { background-color: #8b5cf6; }            QPushButton#connectButton:hover { background-color: #7c3aed; }            QLineEdit, QComboBox, QSpinBox {                border: 1px solid #d0d7de;                border-radius: 4px;                padding: 4px 8px;                background-color: white;                font-size: 11px;            }            QLineEdit:focus, QComboBox:focus, QSpinBox:focus {                border-color: #2d8cf0;                outline: none;            }            QTextEdit {                border: 1px solid #d0d7de;                border-radius: 4px;                background-color: #1a1a2e;                color: #e0e0e0;                font-family: Consolas, "Courier New", monospace;                font-size: 10px;            }            QListWidget {                border: 1px solid #d0d7de;                border-radius: 4px;                background-color: white;                font-size: 10px;            }            QListWidget::item:selected {                background-color: #2d8cf0;                color: white;            }            QListWidget::item:hover { background-color: #e8ecf1; }            QCheckBox { spacing: 6px; font-size: 11px; }            QRadioButton { spacing: 6px; font-size: 11px; }            QProgressBar {                border: 1px solid #d0d7de;                border-radius: 3px;                text-align: center;                height: 18px;                background-color: white;                font-weight: bold;                font-size: 10px;            }            QProgressBar::chunk {                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,                    stop:0 #19be6b, stop:1 #2d8cf0);                border-radius: 3px;            }            QStatusBar {                background-color: #24292f;                color: #e8ecf1;                font-size: 11px;            }            QLabel { font-size: 11px; }            QScrollArea {                border: none;                background-color: transparent;            }            QScrollBar:vertical {                border: none;                background: #f0f2f5;                width: 10px;                border-radius: 5px;            }            QScrollBar::handle:vertical {                background: #c1c7cd;                border-radius: 5px;                min-height: 20px;            }            QScrollBar::handle:vertical:hover { background: #a0a8b0; }            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {                border: none;                background: none;            }        """)        central_widget = QWidget()        self.setCentralWidget(central_widget)        main_layout = QVBoxLayout(central_widget)        main_layout.setSpacing(6)        main_layout.setContentsMargins(8888)        splitter = QSplitter(Qt.Orientation.Horizontal)        main_layout.addWidget(splitter, 1)        left_panel = self.create_left_panel()        splitter.addWidget(left_panel)        right_panel = self.create_right_panel()        splitter.addWidget(right_panel)        splitter.setSizes([450450])        # 状态栏        self.status_bar = self.statusBar()        self.status_label = QLabel("就绪")        self.status_bar.addWidget(self.status_label)        self.progress_bar = QProgressBar()        self.progress_bar.setMaximumWidth(160)        self.progress_bar.setVisible(False)        self.status_bar.addPermanentWidget(self.progress_bar)        self.connection_indicator = QLabel("● 未连接")        self.connection_indicator.setStyleSheet("color: #ed4014; font-weight: bold; font-size: 10px;")        self.status_bar.addPermanentWidget(self.connection_indicator)    def create_left_panel(self) -> QWidget:        """创建左侧设置面板"""        panel = QWidget()        layout = QVBoxLayout(panel)        layout.setSpacing(0)        layout.setContentsMargins(0000)        scroll_area = QScrollArea()        scroll_area.setWidgetResizable(True)        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)        content_widget = QWidget()        content_layout = QVBoxLayout(content_widget)        content_layout.setSpacing(5)        content_layout.setContentsMargins(0080)        # ===== 图框选择 =====        frame_group = QGroupBox("📋 图框选择")        frame_layout = QVBoxLayout(frame_group)        frame_layout.setSpacing(5)        # 连接按钮        connect_layout = QHBoxLayout()        self.btn_connect = QPushButton("🔗 连接 AutoCAD")        self.btn_connect.setObjectName("connectButton")        self.btn_connect.setMinimumHeight(30)        connect_layout.addWidget(self.btn_connect)        self.lbl_connect_status = QLabel("⚪ 未连接")        self.lbl_connect_status.setStyleSheet("color: #ed4014; font-weight: bold; font-size: 11px;")        connect_layout.addWidget(self.lbl_connect_status)        connect_layout.addStretch()        frame_layout.addLayout(connect_layout)        # 分隔线        line = QFrame()        line.setFrameShape(QFrame.Shape.HLine)        line.setFrameShadow(QFrame.Shadow.Sunken)        line.setStyleSheet("background-color: #d0d7de; max-height: 1px;")        frame_layout.addWidget(line)        # 模式选择        mode_layout = QHBoxLayout()        self.frame_mode_group = QButtonGroup()        self.radio_block = QRadioButton("图块")        self.radio_lz = QRadioButton("理正图框")        self.radio_layer = QRadioButton("图层")        self.radio_block.setChecked(True)        self.frame_mode_group.addButton(self.radio_block, 0)        self.frame_mode_group.addButton(self.radio_lz, 1)        self.frame_mode_group.addButton(self.radio_layer, 2)        mode_layout.addWidget(self.radio_block)        mode_layout.addWidget(self.radio_lz)        mode_layout.addWidget(self.radio_layer)        mode_layout.addStretch()        frame_layout.addLayout(mode_layout)        # 图块名称        block_layout = QHBoxLayout()        block_layout.addWidget(QLabel("图块名称:"))        self.cmb_block = QComboBox()        self.cmb_block.setEditable(True)        block_layout.addWidget(self.cmb_block, 1)        frame_layout.addLayout(block_layout)        # 图层名称        layer_layout = QHBoxLayout()        layer_layout.addWidget(QLabel("图层名称:"))        self.cmb_layer = QComboBox()        self.cmb_layer.setEditable(True)        self.cmb_layer.setEnabled(False)        layer_layout.addWidget(self.cmb_layer, 1)        frame_layout.addLayout(layer_layout)        # 操作按钮        select_layout = QHBoxLayout()        self.btn_select = QPushButton("🔍 选择图框")        self.btn_select.setObjectName("successButton")        select_layout.addWidget(self.btn_select)        self.btn_highlight = QPushButton("✨ 高亮显示")        select_layout.addWidget(self.btn_highlight)        select_layout.addStretch()        frame_layout.addLayout(select_layout)        # 图框数量        info_layout = QHBoxLayout()        info_layout.addWidget(QLabel("已选图框:"))        self.lbl_frame_count = QLabel("0 个")        self.lbl_frame_count.setStyleSheet("font-weight: bold; color: #2d8cf0; font-size: 12px;")        info_layout.addWidget(self.lbl_frame_count)        info_layout.addStretch()        frame_layout.addLayout(info_layout)        content_layout.addWidget(frame_group)        # ===== 打印设置 =====        plot_group = QGroupBox("🖨️ 打印设置")        plot_layout = QVBoxLayout(plot_group)        plot_layout.setSpacing(5)        # 输出方式        output_layout = QHBoxLayout()        output_layout.addWidget(QLabel("输出方式:"))        self.cmb_output = QComboBox()        self.cmb_output.addItems(["打印到设备""打印到文件 (PLT)""预览"])        output_layout.addWidget(self.cmb_output, 1)        plot_layout.addLayout(output_layout)        # 打印比例        scale_layout = QHBoxLayout()        scale_layout.addWidget(QLabel("打印比例:"))        self.cmb_scale = QComboBox()        self.cmb_scale.addItems(["自动""适合纸张""1:50""1:75""1:100""1:150""1:200""自定义"])        scale_layout.addWidget(self.cmb_scale, 1)        plot_layout.addLayout(scale_layout)        # 自定义比例        custom_layout = QHBoxLayout()        custom_layout.addWidget(QLabel("自定义 (1:"))        self.spin_scale = QSpinBox()        self.spin_scale.setRange(110000)        self.spin_scale.setValue(100)        self.spin_scale.setEnabled(False)        custom_layout.addWidget(self.spin_scale)        custom_layout.addWidget(QLabel(")"))        custom_layout.addStretch()        plot_layout.addLayout(custom_layout)        # 打印份数        copies_layout = QHBoxLayout()        copies_layout.addWidget(QLabel("打印份数:"))        self.spin_copies = QSpinBox()        self.spin_copies.setRange(1999)        self.spin_copies.setValue(1)        copies_layout.addWidget(self.spin_copies)        copies_layout.addStretch()        plot_layout.addLayout(copies_layout)        # 选项        options_layout = QGridLayout()        options_layout.setSpacing(6)        self.chk_auto_rotate = QCheckBox("自动旋转")        self.chk_auto_rotate.setChecked(True)        options_layout.addWidget(self.chk_auto_rotate, 00)        self.chk_upside_down = QCheckBox("上下颠倒")        options_layout.addWidget(self.chk_upside_down, 01)        self.chk_reverse = QCheckBox("反向顺序")        options_layout.addWidget(self.chk_reverse, 10)        self.chk_center = QCheckBox("居中打印")        self.chk_center.setChecked(True)        options_layout.addWidget(self.chk_center, 11)        plot_layout.addLayout(options_layout)        content_layout.addWidget(plot_group)        # ===== 文件设置 =====        file_group = QGroupBox("📁 文件设置")        file_layout = QVBoxLayout(file_group)        file_layout.setSpacing(5)        # 文件名前缀        file_prefix_layout = QHBoxLayout()        file_prefix_layout.addWidget(QLabel("文件名前缀:"))        self.edit_prefix = QLineEdit("PLOT_")        file_prefix_layout.addWidget(self.edit_prefix, 1)        file_layout.addLayout(file_prefix_layout)        # 保存路径        file_folder_layout = QHBoxLayout()        file_folder_layout.addWidget(QLabel("保存路径:"))        self.edit_folder = QLineEdit()        self.edit_folder.setReadOnly(True)        file_folder_layout.addWidget(self.edit_folder, 1)        self.btn_folder = QPushButton("📁")        self.btn_folder.setFixedWidth(28)        self.btn_folder.setStyleSheet("background-color: #e8ecf1; color: #24292f; padding: 2px;")        file_folder_layout.addWidget(self.btn_folder)        file_layout.addLayout(file_folder_layout)        self.chk_delete_plot = QCheckBox("删除已有打印文件")        file_layout.addWidget(self.chk_delete_plot)        content_layout.addWidget(file_group)        # ===== 布局设置 =====        layout_group = QGroupBox("📐 布局设置")        layout_layout = QVBoxLayout(layout_group)        layout_layout.setSpacing(5)        layout_prefix_layout = QHBoxLayout()        layout_prefix_layout.addWidget(QLabel("布局前缀:"))        self.edit_layout_prefix = QLineEdit("BP_")        layout_prefix_layout.addWidget(self.edit_layout_prefix, 1)        layout_layout.addLayout(layout_prefix_layout)        self.chk_delete_layout = QCheckBox("删除已有同前缀布局")        layout_layout.addWidget(self.chk_delete_layout)        self.chk_ms_line_scale = QCheckBox("模型空间线型比例")        self.chk_ms_line_scale.setChecked(True)        layout_layout.addWidget(self.chk_ms_line_scale)        content_layout.addWidget(layout_group)        # ===== 操作按钮 =====        action_group = QGroupBox("🚀 操作")        action_layout = QGridLayout(action_group)        action_layout.setSpacing(6)        self.btn_plot = QPushButton("🖨️ 批量打印")        self.btn_plot.setObjectName("successButton")        self.btn_plot.setMinimumHeight(36)        action_layout.addWidget(self.btn_plot, 00)        self.btn_layout = QPushButton("📐 生成布局")        self.btn_layout.setObjectName("warningButton")        self.btn_layout.setMinimumHeight(36)        action_layout.addWidget(self.btn_layout, 01)        self.btn_preview = QPushButton("👁️ 预览")        self.btn_preview.setMinimumHeight(32)        action_layout.addWidget(self.btn_preview, 10)        self.btn_cancel = QPushButton("⏹ 取消")        self.btn_cancel.setObjectName("dangerButton")        self.btn_cancel.setMinimumHeight(32)        self.btn_cancel.setEnabled(False)        action_layout.addWidget(self.btn_cancel, 11)        content_layout.addWidget(action_group)        content_layout.addStretch()        scroll_area.setWidget(content_widget)        layout.addWidget(scroll_area)        return panel    def create_right_panel(self) -> QWidget:        """创建右侧面板"""        panel = QWidget()        layout = QVBoxLayout(panel)        layout.setSpacing(5)        layout.setContentsMargins(0000)        # 图框列表        list_group = QGroupBox("📋 图框列表")        list_layout = QVBoxLayout(list_group)        list_layout.setSpacing(4)        self.frame_list = QListWidget()        list_layout.addWidget(self.frame_list)        layout.addWidget(list_group, 1)        # 日志        log_group = QGroupBox("📝 日志")        log_layout = QVBoxLayout(log_group)        log_layout.setSpacing(4)        self.log_text = QTextEdit()        self.log_text.setReadOnly(True)        log_layout.addWidget(self.log_text)        log_control = QHBoxLayout()        log_control.setSpacing(6)        self.btn_clear_log = QPushButton("清空日志")        self.btn_clear_log.setStyleSheet("background-color: #e8ecf1; color: #24292f; padding: 3px 10px; font-size: 10px;")        log_control.addWidget(self.btn_clear_log)        log_control.addStretch()        self.chk_auto_scroll = QCheckBox("自动滚动")        self.chk_auto_scroll.setChecked(True)        self.chk_auto_scroll.setStyleSheet("font-size: 10px;")        log_control.addWidget(self.chk_auto_scroll)        log_layout.addLayout(log_control)        layout.addWidget(log_group, 1)        return panel    def setup_connections(self):        """设置信号连接"""        self.frame_mode_group.buttonClicked.connect(self.on_frame_mode_changed)        self.btn_connect.clicked.connect(self.on_connect_clicked)        self.btn_select.clicked.connect(self.on_select_clicked)        self.btn_highlight.clicked.connect(self.on_highlight_clicked)        self.btn_plot.clicked.connect(self.on_plot_clicked)        self.btn_layout.clicked.connect(self.on_layout_clicked)        self.btn_preview.clicked.connect(self.on_preview_clicked)        self.btn_cancel.clicked.connect(self.on_cancel_clicked)        self.btn_folder.clicked.connect(self.on_folder_clicked)        self.btn_clear_log.clicked.connect(self.on_clear_log_clicked)        self.cmb_scale.currentIndexChanged.connect(self.on_scale_changed)        self.cmb_output.currentIndexChanged.connect(self.on_output_changed)    # ===== 界面事件处理方法 =====    def on_frame_mode_changed(self, button):        """图框模式切换"""        if button == self.radio_block:            self.settings.frame_mode = "BlockRadio"            self.cmb_block.setEnabled(True)            self.cmb_layer.setEnabled(False)        elif button == self.radio_lz:            self.settings.frame_mode = "LzFrameRadio"            self.cmb_block.setEnabled(False)            self.cmb_layer.setEnabled(False)        elif button == self.radio_layer:            self.settings.frame_mode = "LayerRadio"            self.cmb_block.setEnabled(False)            self.cmb_layer.setEnabled(True)    def on_scale_changed(self, index):        """比例选择变化"""        text = self.cmb_scale.currentText()        self.spin_scale.setEnabled(text == "自定义")        if text == "自动":            self.settings.plot_scale = "Auto"        elif text == "适合纸张":            self.settings.plot_scale = "ScaleToFit"        elif text == "自定义":            self.settings.plot_scale = str(self.spin_scale.value())        else:            try:                scale_text = text.replace("1:""")                self.settings.plot_scale = scale_text            except:                self.settings.plot_scale = "Auto"    def on_output_changed(self, index):        """输出方式变化"""        mode = self.cmb_output.currentText()        if mode == "打印到设备":            self.settings.output_mode = "PlotRadio"            self.spin_copies.setEnabled(True)        elif mode == "打印到文件 (PLT)":            self.settings.output_mode = "PlotFileRadio"            self.spin_copies.setEnabled(False)        elif mode == "预览":            self.settings.output_mode = "PreviewRadio"            self.spin_copies.setEnabled(False)    def on_connect_clicked(self):        """连接按钮点击"""        self.log("🔄 正在尝试连接 AutoCAD...")        self.btn_connect.setEnabled(False)        self.btn_connect.setText("⏳ 连接中...")        # 模拟连接成功        from PyQt6.QtCore import QTimer        QTimer.singleShot(1000self._simulate_connect_success)    def _simulate_connect_success(self):        """模拟连接成功"""        self.lbl_connect_status.setText("🟢 已连接")        self.lbl_connect_status.setStyleSheet("color: #19be6b; font-weight: bold; font-size: 11px;")        self.connection_indicator.setText("● 已连接")        self.connection_indicator.setStyleSheet("color: #19be6b; font-weight: bold; font-size: 10px;")        self.btn_connect.setText("🔗 已连接")        self.btn_connect.setStyleSheet("""            QPushButton#connectButton {                background-color: #19be6b;            }            QPushButton#connectButton:hover {                background-color: #16a85a;            }        """)        self.btn_connect.setEnabled(True)        self.log("✅ 成功连接到 AutoCAD")        # 模拟加载图块和图层        self.cmb_block.addItems(["图框A1""图框A2""图框A3""标准图框"])        self.cmb_layer.addItems(["图层1""图层2""图层3"])    def on_select_clicked(self):        """选择图框点击"""        self.log("🔍 正在搜索图框...")        self.update_settings()        # 模拟找到图框        self.frames = [            {"ll": (00), "ur": (10070), "landscape"True},            {"ll": (1200), "ur": (22070), "landscape"True},            {"ll": (2400), "ur": (34070), "landscape"True},        ]        self.frame_list.clear()        for i, bbox in enumerate(self.frames, 1):            orientation = "横向" if bbox["landscape"else "纵向"            item = QListWidgetItem(                f"{i:3d}.  ({bbox['ll'][0]:.1f}, {bbox['ll'][1]:.1f}) → "                f"({bbox['ur'][0]:.1f}, {bbox['ur'][1]:.1f})  [{orientation}]"            )            self.frame_list.addItem(item)        self.lbl_frame_count.setText(f"{len(self.frames)} 个")        self.log(f"✅ 找到 {len(self.frames)} 个图框")    def on_highlight_clicked(self):        """高亮显示点击"""        if not self.frames:            QMessageBox.information(self"提示""请先选择图框")            return        self.log("✨ 高亮显示图框...")        self.log("✅ 高亮显示完成")    def on_plot_clicked(self):        """批量打印点击"""        if not self.frames:            QMessageBox.information(self"提示""请先选择图框")            return        self.update_settings()        self.log("🖨️ 开始批量打印...")        self._simulate_progress("打印")    def on_layout_clicked(self):        """生成布局点击"""        if not self.frames:            QMessageBox.information(self"提示""请先选择图框")            return        self.update_settings()        self.log("📐 开始生成布局...")        self._simulate_progress("布局")    def on_preview_clicked(self):        """预览点击"""        if not self.frames:            QMessageBox.information(self"提示""请先选择图框")            return        self.update_settings()        self.log("👁️ 开始预览...")        self.log("✅ 预览完成")        QMessageBox.information(self"预览""预览功能已触发")    def on_cancel_clicked(self):        """取消点击"""        self.log("⏹ 正在取消操作...")        self.btn_cancel.setEnabled(False)        self.set_buttons_enabled(True)        self.progress_bar.setVisible(False)    def on_folder_clicked(self):        """选择文件夹点击"""        folder = QFileDialog.getExistingDirectory(            self"选择保存路径"self.edit_folder.text() or ""        )        if folder:            self.edit_folder.setText(folder)            self.settings.plot_file_folder = folder            self.log(f"📁 选择保存路径: {folder}")    def on_clear_log_clicked(self):        """清空日志"""        self.log_text.clear()    def _simulate_progress(selfaction: str):        """模拟进度"""        self.set_buttons_enabled(False)        self.progress_bar.setVisible(True)        self.progress_bar.setValue(0)        from PyQt6.QtCore import QTimer        self._progress_value = 0        def update_progress():            self._progress_value += 10            self.progress_bar.setValue(self._progress_value)            self.status_label.setText(f"{action}中... {self._progress_value}%")            self.log(f"{action}中... {self._progress_value}%")            if self._progress_value >= 100:                self.progress_bar.setVisible(False)                self.set_buttons_enabled(True)                self.status_label.setText(f"✅ {action}完成")                self.log(f"✅ {action}完成")                QMessageBox.information(self"完成", f"{action}操作完成")            else:                QTimer.singleShot(300, update_progress)        QTimer.singleShot(300, update_progress)    def update_settings(self):        """更新设置"""        if self.radio_block.isChecked():            self.settings.frame_mode = "BlockRadio"            self.settings.block_name = self.cmb_block.currentText()        elif self.radio_lz.isChecked():            self.settings.frame_mode = "LzFrameRadio"        elif self.radio_layer.isChecked():            self.settings.frame_mode = "LayerRadio"            self.settings.layer_name = self.cmb_layer.currentText()        output_text = self.cmb_output.currentText()        if output_text == "打印到设备":            self.settings.output_mode = "PlotRadio"        elif output_text == "打印到文件 (PLT)":            self.settings.output_mode = "PlotFileRadio"        elif output_text == "预览":            self.settings.output_mode = "PreviewRadio"        scale_text = self.cmb_scale.currentText()        if scale_text == "自动":            self.settings.plot_scale = "Auto"        elif scale_text == "适合纸张":            self.settings.plot_scale = "ScaleToFit"        elif scale_text == "自定义":            self.settings.plot_scale = str(self.spin_scale.value())        else:            try:                scale_text = scale_text.replace("1:""")                self.settings.plot_scale = scale_text            except:                self.settings.plot_scale = "Auto"        self.settings.copies = self.spin_copies.value()        self.settings.auto_rotate = self.chk_auto_rotate.isChecked()        self.settings.upside_down = self.chk_upside_down.isChecked()        self.settings.reverse_order = self.chk_reverse.isChecked()        self.settings.ms_line_scale = self.chk_ms_line_scale.isChecked()        self.settings.layout_prefix = self.edit_layout_prefix.text()        self.settings.plot_file_prefix = self.edit_prefix.text()        self.settings.plot_file_folder = self.edit_folder.text()        self.settings.delete_plot_file = self.chk_delete_plot.isChecked()        self.settings.delete_layout = self.chk_delete_layout.isChecked()    def set_buttons_enabled(selfenabled: bool):        """设置按钮启用状态"""        self.btn_connect.setEnabled(enabled)        self.btn_select.setEnabled(enabled)        self.btn_highlight.setEnabled(enabled)        self.btn_plot.setEnabled(enabled)        self.btn_layout.setEnabled(enabled)        self.btn_preview.setEnabled(enabled)        self.btn_cancel.setEnabled(not enabled)    def log(selfmessage: str):        """添加日志"""        self.log_text.append(message)        if self.chk_auto_scroll.isChecked():            cursor = self.log_text.textCursor()            cursor.movePosition(QTextCursor.MoveOperation.End)            self.log_text.setTextCursor(cursor)def main():    app = QApplication(sys.argv)    app.setApplicationName("BatchPlot")    window = MainWindow()    window.show()    sys.exit(app.exec())if __name__ == "__main__":    main()

            这款AutoCAD批量打印工具,可自动完成原需手动逐张框选、反复调整设置、一张张打印一整天的图纸输出工作。从最初打开图纸来回缩放查找图框、肉眼逐张框选打印区域、手动调整打印比例、反复设置输出路径的繁琐与崩溃,到用自动化工具实现一键搜索图框、批量自动打印、布局智能生成、比例自动适配的畅快,工作效率获得指数级提升,终于解放了双手和时间!

            大佬们也可以举一反三,参照上面的代码思路根据自己工作中的实际情况来具体问题具体分析,实现自己定制化的需求。

            《该办公工具的应用场景:》

              人群
              使用场景

              建筑设计师

              施工图批量打印、布局生成

              结构工程师

              结构图纸批量输

              给排水/暖通/电气设计师

              专业图纸批量打印

              项目负责人

              全套图纸集中打印、分发

              档案管理员

              图纸数字化归档整理

              施工技术人员

              现场施工图批量打印

              结语

              当Python遇见办公,牛马打工人终于笑出了猪叫声

              【职场人必看】每天早上一睁眼,想到又要面对:

              1.📊 堆积如山的Excel表格

              2.📑 机械重复的复制粘贴

              3.✍️ 永远改不完的各类文档

              4.诸如此类的更多........

              是不是连Ctrl+Alt+Delete的心都有了?

              别慌!别急,摸鱼这位“职场外挂”已经带着Python代码来拯救你了!

              另外本篇文章的代码和exe已经上传到nas私有云盘,需要的大佬私信进进群获取下载链接~

              感谢各位大佬观看,还望各位大佬抬抬贵手一键三连,多多关注点赞转发评论,大佬们的支持才是摸鱼孜孜不倦更新原创干货的动力!

              最新文章

              随机文章

              基本 文件 流程 错误 SQL 调试
              1. 请求信息 : 2026-08-21 22:54:40 HTTP/2.0 GET : https://f.mffb.com.cn/a/508615.html
              2. 运行时间 : 0.254455s [ 吞吐率:3.93req/s ] 内存消耗:4,749.16kb 文件加载:140
              3. 缓存信息 : 0 reads,0 writes
              4. 会话信息 : SESSION_ID=3d2e1a1f5d7cedf80bc3e5c6d7716386
              1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
              2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
              3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
              4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
              5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
              6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
              7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
              8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
              9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
              10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
              11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
              12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
              13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
              14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
              15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
              16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
              17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
              18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
              19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
              20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
              21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
              22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
              23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
              24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
              25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
              26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
              27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
              28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
              29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
              30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
              31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
              32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
              33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
              34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
              35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
              36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
              37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
              38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
              39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
              40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
              41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
              42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
              43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
              44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
              45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
              46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
              47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
              48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
              49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
              50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
              51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
              52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
              53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
              54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
              55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
              56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
              57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
              58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
              59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
              60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
              61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
              62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
              63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
              64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
              65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
              66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
              67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
              68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
              69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
              70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
              71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
              72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
              73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
              74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
              75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
              76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
              77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
              78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
              79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
              80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
              81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
              82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
              83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
              84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
              85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
              86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
              87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
              88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
              89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
              90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
              91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
              92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
              93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
              94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
              95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
              96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
              97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
              98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
              99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
              100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
              101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
              102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
              103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
              104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
              105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
              106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
              107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
              108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
              109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
              110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
              111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
              112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
              113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
              114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
              115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
              116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
              117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
              118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
              119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
              120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
              121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
              122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
              123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
              124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
              125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
              126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
              127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
              128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
              129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
              130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
              131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
              132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
              133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
              134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
              135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
              136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
              137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
              138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
              139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
              140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
              1. CONNECT:[ UseTime:0.000425s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
              2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000575s ]
              3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.013593s ]
              4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000330s ]
              5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000764s ]
              6. SELECT * FROM `set` [ RunTime:0.000289s ]
              7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000690s ]
              8. SELECT * FROM `article` WHERE `id` = 508615 LIMIT 1 [ RunTime:0.007292s ]
              9. UPDATE `article` SET `lasttime` = 1787324080 WHERE `id` = 508615 [ RunTime:0.041007s ]
              10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.008582s ]
              11. SELECT * FROM `article` WHERE `id` < 508615 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000578s ]
              12. SELECT * FROM `article` WHERE `id` > 508615 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000553s ]
              13. SELECT * FROM `article` WHERE `id` < 508615 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.036544s ]
              14. SELECT * FROM `article` WHERE `id` < 508615 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.009806s ]
              15. SELECT * FROM `article` WHERE `id` < 508615 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.054423s ]
              0.256051s