refactor(gui): 全部QSpinBox替换为QLineEdit+QIntValidator,去除箭头按钮

This commit is contained in:
2026-07-28 12:02:02 +08:00
parent dea88feb7f
commit 28bdcddf44
+45 -49
View File
@@ -28,7 +28,7 @@ if sys.platform.startswith("win") and "QT_QPA_PLATFORM" not in os.environ:
try: try:
from PySide6.QtCore import QEasingCurve, QEvent, QPropertyAnimation, Qt, QTimer, QUrl 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 ( from PySide6.QtWidgets import (
QApplication, QApplication,
QAbstractItemView, QAbstractItemView,
@@ -46,7 +46,6 @@ try:
QMainWindow, QMainWindow,
QMessageBox, QMessageBox,
QPushButton, QPushButton,
QSpinBox,
QStyle, QStyle,
QTableWidget, QTableWidget,
QTableWidgetItem, QTableWidgetItem,
@@ -502,34 +501,32 @@ class MainWindow(QMainWindow):
open_folder_button.clicked.connect(self.open_swap_gcode_folder) open_folder_button.clicked.connect(self.open_swap_gcode_folder)
# 默认份数 # 默认份数
self.default_copies_spin = QSpinBox() self.default_copies_edit = QLineEdit("1")
self.default_copies_spin.setRange(1, 9999) self.default_copies_edit.setValidator(QIntValidator(1, 9999))
self.default_copies_spin.setValue(1) self.default_copies_edit.setFixedWidth(64)
self.default_copies_spin.setFixedWidth(96)
# 热床降温 # 热床降温
self.bed_cooldown_check = QCheckBox("等待热床降温") self.bed_cooldown_check = QCheckBox("等待热床降温")
self.bed_cooldown_check.setChecked(True) self.bed_cooldown_check.setChecked(True)
self.cool_bed_spin = QSpinBox() self.cool_bed_edit = QLineEdit("45")
self.cool_bed_spin.setRange(0, 120) self.cool_bed_edit.setValidator(QIntValidator(0, 120))
self.cool_bed_spin.setValue(45) self.cool_bed_edit.setFixedWidth(48)
bed_row = QHBoxLayout() bed_row = QHBoxLayout()
bed_row.addWidget(self.bed_cooldown_check) 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.addWidget(QLabel("°C"))
bed_row.addStretch(1) bed_row.addStretch(1)
# 换盘后等待时间(勾选后启用,不勾选则不插入等待指令) # 换盘后等待时间(勾选后启用,不勾选则不插入等待指令)
self.eject_wait_check = QCheckBox("换盘后等待") self.eject_wait_check = QCheckBox("换盘后等待")
self.eject_wait_check.setChecked(True) self.eject_wait_check.setChecked(True)
self.wait_spin = QSpinBox() self.wait_edit = QLineEdit("30")
self.wait_spin.setRange(0, 3600) self.wait_edit.setValidator(QIntValidator(0, 3600))
self.wait_spin.setValue(45) self.wait_edit.setFixedWidth(56)
self.wait_spin.setSuffix("")
self.wait_spin.setFixedWidth(96)
eject_wait_row = QHBoxLayout() eject_wait_row = QHBoxLayout()
eject_wait_row.addWidget(self.eject_wait_check) 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) eject_wait_row.addStretch(1)
# 剩余时间板号显示 # 剩余时间板号显示
@@ -607,7 +604,7 @@ class MainWindow(QMainWindow):
grid.addLayout(swap_btn_row, 0, 3) grid.addLayout(swap_btn_row, 0, 3)
# 第 1 行:默认份数 | 热床降温 # 第 1 行:默认份数 | 热床降温
grid.addWidget(self.default_copies_spin, 1, 1) grid.addWidget(self.default_copies_edit, 1, 1)
grid.addLayout(bed_row, 1, 3) grid.addLayout(bed_row, 1, 3)
# 第 2 行:换盘后等待 | 剩余时间板号 # 第 2 行:换盘后等待 | 剩余时间板号
@@ -712,12 +709,12 @@ class MainWindow(QMainWindow):
def connect_option_signals(self) -> None: def connect_option_signals(self) -> None:
"""将所有选项控件的值变更信号连接到设置保存函数。""" """将所有选项控件的值变更信号连接到设置保存函数。"""
self.swap_gcode_combo.currentIndexChanged.connect(self.save_current_settings) 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.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.stateChanged.connect(self.save_current_settings)
self.eject_wait_check.toggled.connect(self.wait_spin.setEnabled) self.eject_wait_check.toggled.connect(self.wait_edit.setEnabled)
self.wait_spin.valueChanged.connect(self.save_current_settings) self.wait_edit.textChanged.connect(self.save_current_settings)
self.show_plate_number_check.stateChanged.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.swap_final_check.stateChanged.connect(self.save_current_settings)
self.patch_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", {}) options = self._settings.get("packing_options", {})
if not isinstance(options, dict): if not isinstance(options, dict):
return 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.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.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.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.swap_final_check.setChecked(bool(options.get("swap_after_final", True)))
self.patch_check.setChecked(bool(options.get("apply_gcode_patches", True))) self.patch_check.setChecked(bool(options.get("apply_gcode_patches", True)))
@@ -770,11 +767,11 @@ class MainWindow(QMainWindow):
"""从 UI 控件收集当前所有打包选项,返回设置字典。""" """从 UI 控件收集当前所有打包选项,返回设置字典。"""
return { return {
"swap_gcode": self.swap_gcode_combo.currentData() or "", "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(), "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(), "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(), "show_plate_number": self.show_plate_number_check.isChecked(),
"swap_after_final": self.swap_final_check.isChecked(), "swap_after_final": self.swap_final_check.isChecked(),
"apply_gcode_patches": self.patch_check.isChecked(), "apply_gcode_patches": self.patch_check.isChecked(),
@@ -928,17 +925,16 @@ class MainWindow(QMainWindow):
"""刷新所有行的排序控件和份数控件(行号、上下按钮状态)。""" """刷新所有行的排序控件和份数控件(行号、上下按钮状态)。"""
for row in range(self.table.rowCount()): for row in range(self.table.rowCount()):
self.table.setCellWidget(row, ORDER_COLUMN, self.create_order_widget(row)) 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: def create_copies_edit(self, row: int, copies: int) -> QLineEdit:
"""创建份数微调框控件,绑定变更信号。""" """创建份数编辑框控件,绑定文本变更信号。"""
spin = QSpinBox() edit = QLineEdit(str(max(1, int(copies))))
spin.setRange(1, 9999) edit.setValidator(QIntValidator(1, 9999))
spin.setFixedWidth(60) edit.setFixedWidth(60)
spin.setAlignment(Qt.AlignCenter) edit.setAlignment(Qt.AlignCenter)
spin.setValue(max(1, int(copies))) edit.textChanged.connect(lambda text, current_row=row: self.on_row_copies_changed(current_row, text))
spin.valueChanged.connect(lambda value, current_row=row: self.on_row_copies_changed(current_row, value)) return edit
return spin
def row_path(self, row: int) -> Path | None: def row_path(self, row: int) -> Path | None:
"""获取指定行的 3MF 文件路径。""" """获取指定行的 3MF 文件路径。"""
@@ -1016,7 +1012,7 @@ class MainWindow(QMainWindow):
if self.skip_duplicates_check.isChecked() and normalized in existing: if self.skip_duplicates_check.isChecked() and normalized in existing:
skipped += 1 skipped += 1
continue 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) existing.add(normalized)
added += 1 added += 1
else: else:
@@ -1051,7 +1047,7 @@ class MainWindow(QMainWindow):
item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.table.setCellWidget(row, ORDER_COLUMN, self.create_order_widget(row)) self.table.setCellWidget(row, ORDER_COLUMN, self.create_order_widget(row))
self.table.setItem(row, FILE_COLUMN, path_item) 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, TIME_COLUMN, time_item)
self.table.setItem(row, FILAMENT_COLUMN, filament_item) self.table.setItem(row, FILAMENT_COLUMN, filament_item)
self.table.setRowHeight(row, 30) self.table.setRowHeight(row, 30)
@@ -1085,8 +1081,8 @@ class MainWindow(QMainWindow):
def get_row_copies(self, row: int) -> int: def get_row_copies(self, row: int) -> int:
"""获取指定行的份数值。""" """获取指定行的份数值。"""
widget = self.table.cellWidget(row, COPIES_COLUMN) widget = self.table.cellWidget(row, COPIES_COLUMN)
if isinstance(widget, QSpinBox): if isinstance(widget, QLineEdit):
return max(1, int(widget.value())) return max(1, int(widget.text() or 1))
item = self.table.item(row, COPIES_COLUMN) item = self.table.item(row, COPIES_COLUMN)
if item is None: if item is None:
return 1 return 1
@@ -1096,17 +1092,17 @@ class MainWindow(QMainWindow):
return 1 return 1
def set_row_copies(self, row: int, copies: int) -> None: def set_row_copies(self, row: int, copies: int) -> None:
"""设置指定行的份数值(通过微调框或文本)。""" """设置指定行的份数值(通过编辑框或文本)。"""
value = max(1, int(copies)) value = max(1, int(copies))
widget = self.table.cellWidget(row, COPIES_COLUMN) widget = self.table.cellWidget(row, COPIES_COLUMN)
if isinstance(widget, QSpinBox): if isinstance(widget, QLineEdit):
widget.setValue(value) widget.setText(str(value))
return return
item = self.table.item(row, COPIES_COLUMN) item = self.table.item(row, COPIES_COLUMN)
if item is not None: if item is not None:
item.setText(str(value)) 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: if self._updating_table:
return return
@@ -1206,7 +1202,7 @@ class MainWindow(QMainWindow):
for col, item in enumerate(row_items): for col, item in enumerate(row_items):
if item is not None: if item is not None:
self.table.setItem(new_row, col, item) 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) self.table.setRowHeight(new_row, 38)
finally: finally:
self._updating_table = False self._updating_table = False
@@ -1224,7 +1220,7 @@ class MainWindow(QMainWindow):
self._updating_table = True self._updating_table = True
try: try:
for row in rows: 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) self.update_row_stats(row)
finally: finally:
self._updating_table = False self._updating_table = False
@@ -1321,8 +1317,8 @@ class MainWindow(QMainWindow):
swap_gcode_path = self.swap_gcode_combo.currentData() swap_gcode_path = self.swap_gcode_combo.currentData()
if not swap_gcode_path: if not swap_gcode_path:
raise ValueError("请在 swap_gcode 文件夹中放入至少一个换盘 G-code 文件并选择它。") raise ValueError("请在 swap_gcode 文件夹中放入至少一个换盘 G-code 文件并选择它。")
cool_bed_temp = self.cool_bed_spin.value() if self.bed_cooldown_check.isChecked() else None cool_bed_temp = int(self.cool_bed_edit.text() or 45) if self.bed_cooldown_check.isChecked() else None
eject_wait_seconds = self.wait_spin.value() if self.eject_wait_check.isChecked() else 0 eject_wait_seconds = int(self.wait_edit.text() or 30) if self.eject_wait_check.isChecked() else 0
return BuildOptions( return BuildOptions(
swap_gcode=Path(swap_gcode_path), swap_gcode=Path(swap_gcode_path),
output_3mf=output_path, output_3mf=output_path,