From 28bdcddf4497b5cf9a84dbabf3a92a1115872cc3 Mon Sep 17 00:00:00 2001 From: yw1573 Date: Tue, 28 Jul 2026 12:02:02 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gui):=20=E5=85=A8=E9=83=A8QSpinBox?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=B8=BAQLineEdit+QIntValidator=EF=BC=8C?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=E7=AE=AD=E5=A4=B4=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- a1_swap_mod_packer/gui.py | 94 +++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/a1_swap_mod_packer/gui.py b/a1_swap_mod_packer/gui.py index 386f659..fdb03f0 100644 --- a/a1_swap_mod_packer/gui.py +++ b/a1_swap_mod_packer/gui.py @@ -28,7 +28,7 @@ if sys.platform.startswith("win") and "QT_QPA_PLATFORM" not in os.environ: try: from PySide6.QtCore import QEasingCurve, QEvent, QPropertyAnimation, Qt, QTimer, QUrl - from PySide6.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QFont, QIcon, QKeyEvent, QPixmap + from PySide6.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QFont, QIcon, QIntValidator, QKeyEvent, QPixmap from PySide6.QtWidgets import ( QApplication, QAbstractItemView, @@ -46,7 +46,6 @@ try: QMainWindow, QMessageBox, QPushButton, - QSpinBox, QStyle, QTableWidget, QTableWidgetItem, @@ -502,34 +501,32 @@ class MainWindow(QMainWindow): open_folder_button.clicked.connect(self.open_swap_gcode_folder) # 默认份数 - self.default_copies_spin = QSpinBox() - self.default_copies_spin.setRange(1, 9999) - self.default_copies_spin.setValue(1) - self.default_copies_spin.setFixedWidth(96) + self.default_copies_edit = QLineEdit("1") + self.default_copies_edit.setValidator(QIntValidator(1, 9999)) + self.default_copies_edit.setFixedWidth(64) # 热床降温 self.bed_cooldown_check = QCheckBox("等待热床降温") self.bed_cooldown_check.setChecked(True) - self.cool_bed_spin = QSpinBox() - self.cool_bed_spin.setRange(0, 120) - self.cool_bed_spin.setValue(45) + self.cool_bed_edit = QLineEdit("45") + self.cool_bed_edit.setValidator(QIntValidator(0, 120)) + self.cool_bed_edit.setFixedWidth(48) bed_row = QHBoxLayout() bed_row.addWidget(self.bed_cooldown_check) - bed_row.addWidget(self.cool_bed_spin) + bed_row.addWidget(self.cool_bed_edit) bed_row.addWidget(QLabel("°C")) bed_row.addStretch(1) # 换盘后等待时间(勾选后启用,不勾选则不插入等待指令) self.eject_wait_check = QCheckBox("换盘后等待") self.eject_wait_check.setChecked(True) - self.wait_spin = QSpinBox() - self.wait_spin.setRange(0, 3600) - self.wait_spin.setValue(45) - self.wait_spin.setSuffix(" 秒") - self.wait_spin.setFixedWidth(96) + self.wait_edit = QLineEdit("30") + self.wait_edit.setValidator(QIntValidator(0, 3600)) + self.wait_edit.setFixedWidth(56) eject_wait_row = QHBoxLayout() eject_wait_row.addWidget(self.eject_wait_check) - eject_wait_row.addWidget(self.wait_spin) + eject_wait_row.addWidget(self.wait_edit) + eject_wait_row.addWidget(QLabel("秒")) eject_wait_row.addStretch(1) # 剩余时间板号显示 @@ -607,7 +604,7 @@ class MainWindow(QMainWindow): grid.addLayout(swap_btn_row, 0, 3) # 第 1 行:默认份数 | 热床降温 - grid.addWidget(self.default_copies_spin, 1, 1) + grid.addWidget(self.default_copies_edit, 1, 1) grid.addLayout(bed_row, 1, 3) # 第 2 行:换盘后等待 | 剩余时间板号 @@ -712,12 +709,12 @@ class MainWindow(QMainWindow): def connect_option_signals(self) -> None: """将所有选项控件的值变更信号连接到设置保存函数。""" self.swap_gcode_combo.currentIndexChanged.connect(self.save_current_settings) - self.default_copies_spin.valueChanged.connect(self.save_current_settings) + self.default_copies_edit.textChanged.connect(self.save_current_settings) self.bed_cooldown_check.stateChanged.connect(self.save_current_settings) - self.cool_bed_spin.valueChanged.connect(self.save_current_settings) + self.cool_bed_edit.textChanged.connect(self.save_current_settings) self.eject_wait_check.stateChanged.connect(self.save_current_settings) - self.eject_wait_check.toggled.connect(self.wait_spin.setEnabled) - self.wait_spin.valueChanged.connect(self.save_current_settings) + self.eject_wait_check.toggled.connect(self.wait_edit.setEnabled) + self.wait_edit.textChanged.connect(self.save_current_settings) self.show_plate_number_check.stateChanged.connect(self.save_current_settings) self.swap_final_check.stateChanged.connect(self.save_current_settings) self.patch_check.stateChanged.connect(self.save_current_settings) @@ -734,11 +731,11 @@ class MainWindow(QMainWindow): options = self._settings.get("packing_options", {}) if not isinstance(options, dict): return - self.default_copies_spin.setValue(int(options.get("default_copies", 1))) + self.default_copies_edit.setText(str(int(options.get("default_copies", 1)))) self.bed_cooldown_check.setChecked(bool(options.get("bed_cooldown_enabled", True))) - self.cool_bed_spin.setValue(int(options.get("cool_bed_temp", 45))) + self.cool_bed_edit.setText(str(int(options.get("cool_bed_temp", 45)))) self.eject_wait_check.setChecked(bool(options.get("eject_wait_enabled", True))) - self.wait_spin.setValue(int(options.get("wait_after_eject_seconds", 45))) + self.wait_edit.setText(str(int(options.get("wait_after_eject_seconds", 30)))) self.show_plate_number_check.setChecked(bool(options.get("show_plate_number", True))) self.swap_final_check.setChecked(bool(options.get("swap_after_final", True))) self.patch_check.setChecked(bool(options.get("apply_gcode_patches", True))) @@ -770,11 +767,11 @@ class MainWindow(QMainWindow): """从 UI 控件收集当前所有打包选项,返回设置字典。""" return { "swap_gcode": self.swap_gcode_combo.currentData() or "", - "default_copies": self.default_copies_spin.value(), + "default_copies": int(self.default_copies_edit.text() or 1), "bed_cooldown_enabled": self.bed_cooldown_check.isChecked(), - "cool_bed_temp": self.cool_bed_spin.value(), + "cool_bed_temp": int(self.cool_bed_edit.text() or 45), "eject_wait_enabled": self.eject_wait_check.isChecked(), - "wait_after_eject_seconds": self.wait_spin.value(), + "wait_after_eject_seconds": int(self.wait_edit.text() or 30), "show_plate_number": self.show_plate_number_check.isChecked(), "swap_after_final": self.swap_final_check.isChecked(), "apply_gcode_patches": self.patch_check.isChecked(), @@ -928,17 +925,16 @@ class MainWindow(QMainWindow): """刷新所有行的排序控件和份数控件(行号、上下按钮状态)。""" for row in range(self.table.rowCount()): self.table.setCellWidget(row, ORDER_COLUMN, self.create_order_widget(row)) - self.table.setCellWidget(row, COPIES_COLUMN, self.create_copies_spin(row, self.get_row_copies(row))) + self.table.setCellWidget(row, COPIES_COLUMN, self.create_copies_edit(row, self.get_row_copies(row))) - def create_copies_spin(self, row: int, copies: int) -> QSpinBox: - """创建份数微调框控件,绑定值变更信号。""" - spin = QSpinBox() - spin.setRange(1, 9999) - spin.setFixedWidth(60) - spin.setAlignment(Qt.AlignCenter) - spin.setValue(max(1, int(copies))) - spin.valueChanged.connect(lambda value, current_row=row: self.on_row_copies_changed(current_row, value)) - return spin + def create_copies_edit(self, row: int, copies: int) -> QLineEdit: + """创建份数编辑框控件,绑定文本变更信号。""" + edit = QLineEdit(str(max(1, int(copies)))) + edit.setValidator(QIntValidator(1, 9999)) + edit.setFixedWidth(60) + edit.setAlignment(Qt.AlignCenter) + edit.textChanged.connect(lambda text, current_row=row: self.on_row_copies_changed(current_row, text)) + return edit def row_path(self, row: int) -> Path | None: """获取指定行的 3MF 文件路径。""" @@ -1016,7 +1012,7 @@ class MainWindow(QMainWindow): if self.skip_duplicates_check.isChecked() and normalized in existing: skipped += 1 continue - if self.add_file_row(normalized, self.default_copies_spin.value()): + if self.add_file_row(normalized, int(self.default_copies_edit.text() or 1)): existing.add(normalized) added += 1 else: @@ -1051,7 +1047,7 @@ class MainWindow(QMainWindow): item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) self.table.setCellWidget(row, ORDER_COLUMN, self.create_order_widget(row)) self.table.setItem(row, FILE_COLUMN, path_item) - self.table.setCellWidget(row, COPIES_COLUMN, self.create_copies_spin(row, copies)) + self.table.setCellWidget(row, COPIES_COLUMN, self.create_copies_edit(row, copies)) self.table.setItem(row, TIME_COLUMN, time_item) self.table.setItem(row, FILAMENT_COLUMN, filament_item) self.table.setRowHeight(row, 30) @@ -1085,8 +1081,8 @@ class MainWindow(QMainWindow): def get_row_copies(self, row: int) -> int: """获取指定行的份数值。""" widget = self.table.cellWidget(row, COPIES_COLUMN) - if isinstance(widget, QSpinBox): - return max(1, int(widget.value())) + if isinstance(widget, QLineEdit): + return max(1, int(widget.text() or 1)) item = self.table.item(row, COPIES_COLUMN) if item is None: return 1 @@ -1096,17 +1092,17 @@ class MainWindow(QMainWindow): return 1 def set_row_copies(self, row: int, copies: int) -> None: - """设置指定行的份数值(通过微调框或文本)。""" + """设置指定行的份数值(通过编辑框或文本)。""" value = max(1, int(copies)) widget = self.table.cellWidget(row, COPIES_COLUMN) - if isinstance(widget, QSpinBox): - widget.setValue(value) + if isinstance(widget, QLineEdit): + widget.setText(str(value)) return item = self.table.item(row, COPIES_COLUMN) if item is not None: item.setText(str(value)) - def on_row_copies_changed(self, row: int, copies: int) -> None: + def on_row_copies_changed(self, row: int, text: str) -> None: """份数变更时:刷新该行统计、总合计和输出预览。""" if self._updating_table: return @@ -1206,7 +1202,7 @@ class MainWindow(QMainWindow): for col, item in enumerate(row_items): if item is not None: self.table.setItem(new_row, col, item) - self.table.setCellWidget(new_row, COPIES_COLUMN, self.create_copies_spin(new_row, copies)) + self.table.setCellWidget(new_row, COPIES_COLUMN, self.create_copies_edit(new_row, copies)) self.table.setRowHeight(new_row, 38) finally: self._updating_table = False @@ -1224,7 +1220,7 @@ class MainWindow(QMainWindow): self._updating_table = True try: for row in rows: - self.set_row_copies(row, self.default_copies_spin.value()) + self.set_row_copies(row, int(self.default_copies_edit.text() or 1)) self.update_row_stats(row) finally: self._updating_table = False @@ -1321,8 +1317,8 @@ class MainWindow(QMainWindow): swap_gcode_path = self.swap_gcode_combo.currentData() if not swap_gcode_path: raise ValueError("请在 swap_gcode 文件夹中放入至少一个换盘 G-code 文件并选择它。") - cool_bed_temp = self.cool_bed_spin.value() if self.bed_cooldown_check.isChecked() else None - eject_wait_seconds = self.wait_spin.value() if self.eject_wait_check.isChecked() else 0 + cool_bed_temp = int(self.cool_bed_edit.text() or 45) if self.bed_cooldown_check.isChecked() else None + eject_wait_seconds = int(self.wait_edit.text() or 30) if self.eject_wait_check.isChecked() else 0 return BuildOptions( swap_gcode=Path(swap_gcode_path), output_3mf=output_path,