"""BatchPlot - AutoCAD批量打印工具 """import sysfrom typing import List, Optionalfrom dataclasses import dataclass, fieldfrom PyQt6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, QPushButton, QComboBox, QSpinBox, QCheckBox, QRadioButton, QButtonGroup, QTextEdit, QFileDialog, QMessageBox, QLineEdit, QListWidget, QListWidgetItem, QSplitter, QGridLayout, QProgressBar, QScrollArea, QFrame)from PyQt6.QtCore import Qtfrom PyQt6.QtGui import QFont, QTextCursor@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(900, 650) 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(8, 8, 8, 8) 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([450, 450]) # 状态栏 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(0, 0, 0, 0) 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(0, 0, 8, 0) # ===== 图框选择 ===== 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(1, 10000) 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(1, 999) 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, 0, 0) self.chk_upside_down = QCheckBox("上下颠倒") options_layout.addWidget(self.chk_upside_down, 0, 1) self.chk_reverse = QCheckBox("反向顺序") options_layout.addWidget(self.chk_reverse, 1, 0) self.chk_center = QCheckBox("居中打印") self.chk_center.setChecked(True) options_layout.addWidget(self.chk_center, 1, 1) 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, 0, 0) self.btn_layout = QPushButton("📐 生成布局") self.btn_layout.setObjectName("warningButton") self.btn_layout.setMinimumHeight(36) action_layout.addWidget(self.btn_layout, 0, 1) self.btn_preview = QPushButton("👁️ 预览") self.btn_preview.setMinimumHeight(32) action_layout.addWidget(self.btn_preview, 1, 0) 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, 1, 1) 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(0, 0, 0, 0) # 图框列表 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(1000, self._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": (0, 0), "ur": (100, 70), "landscape": True}, {"ll": (120, 0), "ur": (220, 70), "landscape": True}, {"ll": (240, 0), "ur": (340, 70), "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(self, action: 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(self, enabled: 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(self, message: 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()