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:
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,