gcode预览测试
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
from PyQt6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel,
|
||||
QFrame, QGridLayout, QSizePolicy, QLineEdit,
|
||||
QFrame, QGridLayout, QSizePolicy, QLineEdit, QApplication,
|
||||
)
|
||||
from PyQt6.QtCore import Qt, QTimer, QPointF, QRectF
|
||||
from PyQt6.QtCore import Qt, QTimer, QPointF, QRectF, QEvent
|
||||
from PyQt6.QtGui import QFont, QPainter, QColor, QBrush, QPen, QDoubleValidator
|
||||
from utils.config_parse import ConfigParse
|
||||
from utils.floating_keyboard import FloatingKeyboard
|
||||
|
||||
MOVE_STEP = 10 # 每次点击移动 mm (保留备用)
|
||||
|
||||
@@ -222,6 +223,16 @@ class ControlPage(QWidget):
|
||||
self._homed = False # 是否已轴回零
|
||||
self._motor_on = True # 电机是否已使能(默认True,关电机后置False)
|
||||
|
||||
# 归零后的停留位置
|
||||
hp = self.config_parser.home_positions or {}
|
||||
self._home_x = hp.get("x", 0.0)
|
||||
self._home_y = hp.get("y", 0.0)
|
||||
self._home_z = hp.get("z", 0.0)
|
||||
|
||||
# 悬浮键盘
|
||||
self._keyboard = FloatingKeyboard()
|
||||
self._keyboard_attached = False
|
||||
|
||||
self.init_ui()
|
||||
self._sync_inputs()
|
||||
self._apply_state()
|
||||
@@ -371,7 +382,9 @@ class ControlPage(QWidget):
|
||||
|
||||
def _cmd_home(self):
|
||||
self.api_client.home_axes(["x", "y", "z"])
|
||||
self.pos_x = self.pos_y = self.pos_z = 0.0
|
||||
self.pos_x = self._home_x
|
||||
self.pos_y = self._home_y
|
||||
self.pos_z = self._home_z
|
||||
self._homed = True
|
||||
self._motor_on = True
|
||||
self._sync_inputs()
|
||||
@@ -385,6 +398,45 @@ class ControlPage(QWidget):
|
||||
self._motor_on = False
|
||||
self._apply_state()
|
||||
|
||||
# ── 悬浮键盘 ─────────────────────────────────────────────
|
||||
|
||||
def _attach_keyboard(self, widget):
|
||||
"""将悬浮键盘绑定到指定输入框并显示"""
|
||||
self._keyboard.attach(widget)
|
||||
self._keyboard.show_below(widget)
|
||||
self._keyboard_attached = True
|
||||
|
||||
def _dismiss_keyboard(self):
|
||||
"""关闭悬浮键盘"""
|
||||
self._keyboard.hide()
|
||||
self._keyboard.detach()
|
||||
self._keyboard_attached = False
|
||||
|
||||
def _on_input_focus_in(self, widget):
|
||||
"""输入框获得焦点时的处理"""
|
||||
if self._keyboard_attached:
|
||||
self._keyboard.attach(widget)
|
||||
self._keyboard.show_below(widget)
|
||||
else:
|
||||
self._attach_keyboard(widget)
|
||||
|
||||
def eventFilter(self, obj, event):
|
||||
if event.type() == QEvent.Type.FocusIn:
|
||||
if obj in (self.input_x, self.input_y, self.input_z):
|
||||
self._on_input_focus_in(obj)
|
||||
elif self._keyboard_attached and not isinstance(obj, QLineEdit):
|
||||
self._dismiss_keyboard()
|
||||
elif event.type() == QEvent.Type.FocusOut:
|
||||
if obj in (self.input_x, self.input_y, self.input_z):
|
||||
QTimer.singleShot(100, self._check_dismiss_keyboard)
|
||||
return super().eventFilter(obj, event)
|
||||
|
||||
def _check_dismiss_keyboard(self):
|
||||
"""检查当前焦点是否还在坐标输入框上,不在则关闭键盘"""
|
||||
w = self.focusWidget()
|
||||
if w not in (self.input_x, self.input_y, self.input_z):
|
||||
self._dismiss_keyboard()
|
||||
|
||||
# ── UI 构建 ──────────────────────────────────────────────
|
||||
|
||||
def init_ui(self):
|
||||
@@ -511,6 +563,7 @@ class ControlPage(QWidget):
|
||||
inp.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
inp.setValidator(QDoubleValidator(-9999, 9999, 1))
|
||||
inp.returnPressed.connect(self._on_coord_changed)
|
||||
inp.installEventFilter(self)
|
||||
setattr(self, f"input_{axis.lower()}", inp)
|
||||
coord_row.addWidget(inp)
|
||||
|
||||
|
||||
@@ -132,6 +132,94 @@ class WifiScanWorker(QObject):
|
||||
self.scan_error.emit(str(e))
|
||||
|
||||
|
||||
class WifiConnectWorker(QObject):
|
||||
"""在后台线程中连接新WiFi"""
|
||||
finished = pyqtSignal(bool, str) # (success, ssid)
|
||||
error = pyqtSignal(str)
|
||||
|
||||
def __init__(self, wifi_manager, auth_mode, ssid, password=None, identity=None):
|
||||
super().__init__()
|
||||
self.wifi_manager = wifi_manager
|
||||
self.auth_mode = auth_mode
|
||||
self.ssid = ssid
|
||||
self.password = password
|
||||
self.identity = identity
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
if self.auth_mode == "open":
|
||||
ok = self.wifi_manager.connect_wifi(self.ssid, None)
|
||||
elif self.auth_mode == "psk":
|
||||
ok = self.wifi_manager.connect_wifi(self.ssid, self.password)
|
||||
else:
|
||||
ok = self.wifi_manager.connect_eap(self.ssid, self.identity, self.password)
|
||||
self.finished.emit(ok, self.ssid)
|
||||
except Exception as e:
|
||||
self.error.emit(str(e))
|
||||
|
||||
|
||||
class WifiConnectSavedWorker(QObject):
|
||||
"""在后台线程中连接已保存的网络"""
|
||||
finished = pyqtSignal(bool, str)
|
||||
error = pyqtSignal(str)
|
||||
|
||||
def __init__(self, wifi_manager, network_id, ssid):
|
||||
super().__init__()
|
||||
self.wifi_manager = wifi_manager
|
||||
self.network_id = network_id
|
||||
self.ssid = ssid
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
ok = self.wifi_manager.connect_network_id(self.network_id)
|
||||
self.finished.emit(ok, self.ssid)
|
||||
except Exception as e:
|
||||
self.error.emit(str(e))
|
||||
|
||||
|
||||
class WifiRemoveWorker(QObject):
|
||||
"""在后台线程中删除已保存的网络"""
|
||||
finished = pyqtSignal(bool, str)
|
||||
error = pyqtSignal(str)
|
||||
|
||||
def __init__(self, wifi_manager, network_id, ssid):
|
||||
super().__init__()
|
||||
self.wifi_manager = wifi_manager
|
||||
self.network_id = network_id
|
||||
self.ssid = ssid
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.wifi_manager.remove_network(self.network_id)
|
||||
self.finished.emit(True, self.ssid)
|
||||
except Exception as e:
|
||||
self.error.emit(str(e))
|
||||
|
||||
|
||||
class WifiHotspotWorker(QObject):
|
||||
"""在后台线程中开启/关闭热点"""
|
||||
finished = pyqtSignal(bool, str)
|
||||
error = pyqtSignal(str)
|
||||
|
||||
def __init__(self, wifi_manager, action, ssid=None, password=None):
|
||||
super().__init__()
|
||||
self.wifi_manager = wifi_manager
|
||||
self.action = action
|
||||
self.ssid = ssid
|
||||
self.password = password
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
if self.action == "open":
|
||||
ret = self.wifi_manager.open_hotspot(self.ssid, self.password)
|
||||
self.finished.emit(bool(ret), self.ssid or "")
|
||||
else:
|
||||
self.wifi_manager.close_hotspot()
|
||||
self.finished.emit(True, "")
|
||||
except Exception as e:
|
||||
self.error.emit(str(e))
|
||||
|
||||
|
||||
class SettingPage(QWidget):
|
||||
def __init__(self, api_client, parent=None):
|
||||
super().__init__(parent)
|
||||
@@ -451,13 +539,13 @@ class SettingPage(QWidget):
|
||||
|
||||
saved_buttons_layout = QHBoxLayout()
|
||||
saved_buttons_layout.setSpacing(12)
|
||||
connect_saved_button = QPushButton("连接到此网络")
|
||||
connect_saved_button.clicked.connect(self.connect_to_saved_wifi)
|
||||
saved_buttons_layout.addWidget(connect_saved_button)
|
||||
self.connect_saved_button = QPushButton("连接到此网络")
|
||||
self.connect_saved_button.clicked.connect(self.connect_to_saved_wifi)
|
||||
saved_buttons_layout.addWidget(self.connect_saved_button)
|
||||
|
||||
remove_saved_button = QPushButton("删除选中")
|
||||
remove_saved_button.clicked.connect(self.remove_selected_saved_wifi)
|
||||
saved_buttons_layout.addWidget(remove_saved_button)
|
||||
self.remove_saved_button = QPushButton("删除选中")
|
||||
self.remove_saved_button.clicked.connect(self.remove_selected_saved_wifi)
|
||||
saved_buttons_layout.addWidget(self.remove_saved_button)
|
||||
wifi_layout.addLayout(saved_buttons_layout)
|
||||
|
||||
nearby_title = QLabel("附近网络")
|
||||
@@ -547,8 +635,8 @@ class SettingPage(QWidget):
|
||||
wifi_layout.addLayout(form)
|
||||
|
||||
# 连接按钮使用醒目的强调色
|
||||
connect_button = QPushButton("连接")
|
||||
connect_button.setStyleSheet(
|
||||
self.connect_button = QPushButton("连接")
|
||||
self.connect_button.setStyleSheet(
|
||||
"""
|
||||
QPushButton {
|
||||
min-height: 52px;
|
||||
@@ -570,8 +658,8 @@ class SettingPage(QWidget):
|
||||
}
|
||||
"""
|
||||
)
|
||||
connect_button.clicked.connect(self.connect_to_wifi)
|
||||
wifi_layout.addWidget(connect_button)
|
||||
self.connect_button.clicked.connect(self.connect_to_wifi)
|
||||
wifi_layout.addWidget(self.connect_button)
|
||||
|
||||
wifi_layout.addStretch()
|
||||
self.settings_stack.addWidget(self._wrap_scroll(wifi_widget))
|
||||
@@ -722,47 +810,101 @@ class SettingPage(QWidget):
|
||||
self.hotspot_toggle.setText("OFF")
|
||||
|
||||
def _on_hotspot_toggled(self, checked):
|
||||
# 立即阻塞信号,防止递归触发
|
||||
self.hotspot_toggle.blockSignals(True)
|
||||
|
||||
if checked:
|
||||
ssid = self.hotspot_ssid.text().strip()
|
||||
password = self.hotspot_password.text().strip()
|
||||
if not ssid:
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", "请输入热点名称")
|
||||
self.hotspot_toggle.blockSignals(True)
|
||||
self.hotspot_toggle.setChecked(False)
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", "请输入热点名称")
|
||||
return
|
||||
if len(password) < 8:
|
||||
self.hotspot_toggle.setChecked(False)
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", "密码至少需要8位")
|
||||
self.hotspot_toggle.blockSignals(True)
|
||||
self.hotspot_toggle.setChecked(False)
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
return
|
||||
try:
|
||||
ret = self.wifi_manager.open_hotspot(ssid, password)
|
||||
if ret:
|
||||
self._apply_toggle_style(True)
|
||||
self.hotspot_status.setText(f"热点状态:已开启 ({ssid})")
|
||||
self.hotspot_ssid.setEnabled(False)
|
||||
self.hotspot_password.setEnabled(False)
|
||||
self._generate_qr_code(ssid, password)
|
||||
else:
|
||||
raise RuntimeError("wpa_cli 返回失败")
|
||||
except Exception as e:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"开启热点失败: {str(e)}")
|
||||
self.hotspot_toggle.blockSignals(True)
|
||||
self.hotspot_toggle.setChecked(False)
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
|
||||
# 按钮UI反馈 → 显示"开启中……"
|
||||
self.hotspot_toggle.setEnabled(False)
|
||||
self.hotspot_toggle.setText("开启中……")
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
|
||||
self._hotspot_thread = QThread()
|
||||
self._hotspot_worker = WifiHotspotWorker(self.wifi_manager, "open", ssid, password)
|
||||
self._hotspot_worker.moveToThread(self._hotspot_thread)
|
||||
self._hotspot_thread.started.connect(self._hotspot_worker.run)
|
||||
self._hotspot_worker.finished.connect(self._on_hotspot_open_finished)
|
||||
self._hotspot_worker.error.connect(self._on_hotspot_open_error)
|
||||
self._hotspot_worker.finished.connect(self._hotspot_thread.quit)
|
||||
self._hotspot_worker.error.connect(self._hotspot_thread.quit)
|
||||
self._hotspot_worker.finished.connect(self._hotspot_worker.deleteLater)
|
||||
self._hotspot_worker.error.connect(self._hotspot_worker.deleteLater)
|
||||
self._hotspot_thread.finished.connect(self._hotspot_thread.deleteLater)
|
||||
self._hotspot_thread.start()
|
||||
else:
|
||||
try:
|
||||
self.wifi_manager.close_hotspot()
|
||||
except Exception:
|
||||
pass
|
||||
# 关闭热点
|
||||
self.hotspot_toggle.setEnabled(False)
|
||||
self.hotspot_toggle.setText("关闭中……")
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
|
||||
self._hotspot_thread = QThread()
|
||||
self._hotspot_worker = WifiHotspotWorker(self.wifi_manager, "close")
|
||||
self._hotspot_worker.moveToThread(self._hotspot_thread)
|
||||
self._hotspot_thread.started.connect(self._hotspot_worker.run)
|
||||
self._hotspot_worker.finished.connect(self._on_hotspot_close_finished)
|
||||
self._hotspot_worker.error.connect(self._on_hotspot_close_error)
|
||||
self._hotspot_worker.finished.connect(self._hotspot_thread.quit)
|
||||
self._hotspot_worker.error.connect(self._hotspot_thread.quit)
|
||||
self._hotspot_worker.finished.connect(self._hotspot_worker.deleteLater)
|
||||
self._hotspot_worker.error.connect(self._hotspot_worker.deleteLater)
|
||||
self._hotspot_thread.finished.connect(self._hotspot_thread.deleteLater)
|
||||
self._hotspot_thread.start()
|
||||
|
||||
def _on_hotspot_open_finished(self, ok, ssid):
|
||||
if ok:
|
||||
self._apply_toggle_style(True)
|
||||
self.hotspot_status.setText(f"热点状态:已开启 ({ssid})")
|
||||
self.hotspot_ssid.setEnabled(False)
|
||||
self.hotspot_password.setEnabled(False)
|
||||
self._generate_qr_code(ssid, self.hotspot_password.text().strip())
|
||||
else:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", "开启热点失败: wpa_cli 返回失败")
|
||||
self.hotspot_toggle.blockSignals(True)
|
||||
self.hotspot_toggle.setChecked(False)
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
self._apply_toggle_style(False)
|
||||
self.hotspot_status.setText("热点状态:关闭")
|
||||
self.hotspot_ssid.setEnabled(True)
|
||||
self.hotspot_password.setEnabled(True)
|
||||
self.qr_label.clear()
|
||||
self.qr_hint.setText("开启热点后自动生成二维码")
|
||||
self.hotspot_toggle.setEnabled(True)
|
||||
|
||||
def _on_hotspot_open_error(self, err_msg):
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"开启热点失败: {err_msg}")
|
||||
self.hotspot_toggle.blockSignals(True)
|
||||
self.hotspot_toggle.setChecked(False)
|
||||
self.hotspot_toggle.blockSignals(False)
|
||||
self._apply_toggle_style(False)
|
||||
self.hotspot_toggle.setEnabled(True)
|
||||
|
||||
def _on_hotspot_close_finished(self, ok, _msg):
|
||||
self._apply_toggle_style(False)
|
||||
self.hotspot_status.setText("热点状态:关闭")
|
||||
self.hotspot_ssid.setEnabled(True)
|
||||
self.hotspot_password.setEnabled(True)
|
||||
self.qr_label.clear()
|
||||
self.qr_hint.setText("开启热点后自动生成二维码")
|
||||
self.hotspot_toggle.setEnabled(True)
|
||||
|
||||
def _on_hotspot_close_error(self, err_msg):
|
||||
# 关闭失败仍尝试恢复UI
|
||||
self._apply_toggle_style(False)
|
||||
self.hotspot_status.setText("热点状态:关闭")
|
||||
self.hotspot_ssid.setEnabled(True)
|
||||
self.hotspot_password.setEnabled(True)
|
||||
self.qr_label.clear()
|
||||
self.qr_hint.setText("开启热点后自动生成二维码")
|
||||
self.hotspot_toggle.setEnabled(True)
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", f"关闭热点时出现异常: {err_msg}")
|
||||
|
||||
def _generate_qr_code(self, ssid, password):
|
||||
"""生成 WiFi 二维码并显示"""
|
||||
@@ -943,7 +1085,7 @@ class SettingPage(QWidget):
|
||||
|
||||
self.saved_wifi_list.clear()
|
||||
for network in saved_networks:
|
||||
item_text = f"[{network.get('network_id', '-')}] {network.get('ssid', '<hidden>')} {network.get('flags', '')}"
|
||||
item_text = f"{network.get('ssid', '<hidden>')}"
|
||||
item = QListWidgetItem(item_text)
|
||||
item.setData(Qt.ItemDataRole.UserRole, network)
|
||||
self.saved_wifi_list.addItem(item)
|
||||
@@ -1016,7 +1158,11 @@ class SettingPage(QWidget):
|
||||
|
||||
ssid_label = QLabel(decoded_ssid)
|
||||
ssid_label.setStyleSheet("background: transparent; color: #f2f2f2; font-size: 18px;")
|
||||
signal_label = QLabel(f"{signal} dBm" if signal else "")
|
||||
try:
|
||||
signal = int(signal)
|
||||
except (ValueError, TypeError):
|
||||
signal = 0
|
||||
signal_label = QLabel(f"{signal} dBm" if signal < 0 else f"{signal}%")
|
||||
signal_label.setStyleSheet("background: transparent; color: #aaaaaa; font-size: 16px;")
|
||||
|
||||
item_layout.addWidget(ssid_label)
|
||||
@@ -1165,7 +1311,7 @@ class SettingPage(QWidget):
|
||||
self.refresh_current_status()
|
||||
|
||||
def connect_to_saved_wifi(self):
|
||||
"""连接已保存列表中选中的网络"""
|
||||
"""连接已保存列表中选中的网络(后台线程)"""
|
||||
item = self.saved_wifi_list.currentItem()
|
||||
if item is None:
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", "请先选择一个已保存网络")
|
||||
@@ -1176,14 +1322,38 @@ class SettingPage(QWidget):
|
||||
if network_id is None:
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", "选中网络无效")
|
||||
return
|
||||
try:
|
||||
ok = self.wifi_manager.connect_network_id(network_id)
|
||||
if not ok:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", "连接请求下发失败")
|
||||
return
|
||||
self._styled_message(QMessageBox.Icon.Information, self, "成功", f"已发起连接: {ssid}")
|
||||
except Exception as e:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"连接失败: {str(e)}")
|
||||
|
||||
# 按钮UI反馈
|
||||
self.connect_saved_button.setEnabled(False)
|
||||
self.connect_saved_button.setText("连接中……")
|
||||
|
||||
self._saved_connect_thread = QThread()
|
||||
self._saved_connect_worker = WifiConnectSavedWorker(self.wifi_manager, network_id, ssid)
|
||||
self._saved_connect_worker.moveToThread(self._saved_connect_thread)
|
||||
self._saved_connect_thread.started.connect(self._saved_connect_worker.run)
|
||||
self._saved_connect_worker.finished.connect(self._on_saved_connect_finished)
|
||||
self._saved_connect_worker.error.connect(self._on_saved_connect_error)
|
||||
self._saved_connect_worker.finished.connect(self._saved_connect_thread.quit)
|
||||
self._saved_connect_worker.error.connect(self._saved_connect_thread.quit)
|
||||
self._saved_connect_worker.finished.connect(self._saved_connect_worker.deleteLater)
|
||||
self._saved_connect_worker.error.connect(self._saved_connect_worker.deleteLater)
|
||||
self._saved_connect_thread.finished.connect(self._saved_connect_thread.deleteLater)
|
||||
self._saved_connect_thread.start()
|
||||
|
||||
def _on_saved_connect_finished(self, ok, ssid):
|
||||
self.connect_saved_button.setEnabled(True)
|
||||
self.connect_saved_button.setText("连接到此网络")
|
||||
if ok:
|
||||
self._styled_message(QMessageBox.Icon.Information, self, "成功", f"已连接: {ssid}")
|
||||
else:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", "连接失败")
|
||||
self.refresh_saved_wifi()
|
||||
self.refresh_current_status()
|
||||
|
||||
def _on_saved_connect_error(self, err_msg):
|
||||
self.connect_saved_button.setEnabled(True)
|
||||
self.connect_saved_button.setText("连接到此网络")
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"连接失败: {err_msg}")
|
||||
|
||||
def remove_selected_saved_wifi(self):
|
||||
item = self.saved_wifi_list.currentItem()
|
||||
@@ -1196,13 +1366,36 @@ class SettingPage(QWidget):
|
||||
if network_id is None:
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "提示", "选中网络无效,无法删除")
|
||||
return
|
||||
try:
|
||||
self.wifi_manager.remove_network(network_id)
|
||||
|
||||
# 按钮UI反馈
|
||||
self.remove_saved_button.setEnabled(False)
|
||||
self.remove_saved_button.setText("删除中……")
|
||||
|
||||
self._remove_thread = QThread()
|
||||
self._remove_worker = WifiRemoveWorker(self.wifi_manager, network_id, ssid)
|
||||
self._remove_worker.moveToThread(self._remove_thread)
|
||||
self._remove_thread.started.connect(self._remove_worker.run)
|
||||
self._remove_worker.finished.connect(self._on_remove_finished)
|
||||
self._remove_worker.error.connect(self._on_remove_error)
|
||||
self._remove_worker.finished.connect(self._remove_thread.quit)
|
||||
self._remove_worker.error.connect(self._remove_thread.quit)
|
||||
self._remove_worker.finished.connect(self._remove_worker.deleteLater)
|
||||
self._remove_worker.error.connect(self._remove_worker.deleteLater)
|
||||
self._remove_thread.finished.connect(self._remove_thread.deleteLater)
|
||||
self._remove_thread.start()
|
||||
|
||||
def _on_remove_finished(self, ok, ssid):
|
||||
self.remove_saved_button.setEnabled(True)
|
||||
self.remove_saved_button.setText("删除选中")
|
||||
if ok:
|
||||
self._styled_message(QMessageBox.Icon.Information, self, "成功", f"已删除网络: {ssid}")
|
||||
self.refresh_saved_wifi()
|
||||
self.refresh_current_status()
|
||||
except Exception as e:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"删除失败: {str(e)}")
|
||||
self.refresh_saved_wifi()
|
||||
self.refresh_current_status()
|
||||
|
||||
def _on_remove_error(self, err_msg):
|
||||
self.remove_saved_button.setEnabled(True)
|
||||
self.remove_saved_button.setText("删除选中")
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"删除失败: {err_msg}")
|
||||
|
||||
def connect_to_wifi(self):
|
||||
ssid = self.ssid_input.text().strip()
|
||||
@@ -1222,23 +1415,37 @@ class SettingPage(QWidget):
|
||||
self._styled_message(QMessageBox.Icon.Warning, self, "警告", "WPA-EAP 认证需要身份和密码")
|
||||
return
|
||||
|
||||
try:
|
||||
if auth_mode == "open":
|
||||
ok = self.wifi_manager.connect_wifi(ssid, None)
|
||||
elif auth_mode == "psk":
|
||||
ok = self.wifi_manager.connect_wifi(ssid, password)
|
||||
else:
|
||||
ok = self.wifi_manager.connect_eap(ssid, identity, password)
|
||||
# 按钮UI反馈
|
||||
self.connect_button.setEnabled(False)
|
||||
self.connect_button.setText("连接中……")
|
||||
|
||||
if not ok:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", "连接请求下发失败,请检查系统日志")
|
||||
return
|
||||
self._connect_thread = QThread()
|
||||
self._connect_worker = WifiConnectWorker(self.wifi_manager, auth_mode, ssid, password, identity)
|
||||
self._connect_worker.moveToThread(self._connect_thread)
|
||||
self._connect_thread.started.connect(self._connect_worker.run)
|
||||
self._connect_worker.finished.connect(self._on_connect_finished)
|
||||
self._connect_worker.error.connect(self._on_connect_error)
|
||||
self._connect_worker.finished.connect(self._connect_thread.quit)
|
||||
self._connect_worker.error.connect(self._connect_thread.quit)
|
||||
self._connect_worker.finished.connect(self._connect_worker.deleteLater)
|
||||
self._connect_worker.error.connect(self._connect_worker.deleteLater)
|
||||
self._connect_thread.finished.connect(self._connect_thread.deleteLater)
|
||||
self._connect_thread.start()
|
||||
|
||||
self._styled_message(QMessageBox.Icon.Information, self, "成功", f"已发起连接: {ssid}")
|
||||
self.refresh_saved_wifi()
|
||||
self.refresh_current_status()
|
||||
except Exception as e:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"连接WiFi失败: {str(e)}")
|
||||
def _on_connect_finished(self, ok, ssid):
|
||||
self.connect_button.setEnabled(True)
|
||||
self.connect_button.setText("连接")
|
||||
if ok:
|
||||
self._styled_message(QMessageBox.Icon.Information, self, "成功", f"已连接: {ssid}")
|
||||
else:
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", "连接失败")
|
||||
self.refresh_saved_wifi()
|
||||
self.refresh_current_status()
|
||||
|
||||
def _on_connect_error(self, err_msg):
|
||||
self.connect_button.setEnabled(True)
|
||||
self.connect_button.setText("连接")
|
||||
self._styled_message(QMessageBox.Icon.Critical, self, "错误", f"连接WiFi失败: {err_msg}")
|
||||
|
||||
def display_setting(self, index):
|
||||
if index < 0:
|
||||
|
||||
@@ -7,18 +7,11 @@ from PyQt6.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout,
|
||||
from PyQt6.QtCore import Qt, QTimer, QThread, pyqtSignal, QUrl, QObject, pyqtProperty, QRectF, QSize
|
||||
from PyQt6.QtGui import QColor, QPen, QPainter, QPainterPath, QFont, QLinearGradient, QBrush
|
||||
from utils.config_parse import ConfigParse
|
||||
import sys
|
||||
import os
|
||||
from utils.gcode_viewer import GCodeViewerWidget
|
||||
|
||||
|
||||
def get_gcode_dir():
|
||||
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json")
|
||||
try:
|
||||
with open(config_path, "r", encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
return config.get("GCODE_DIR", "/home/lhye200/.octoprint/uploads")
|
||||
except:
|
||||
return "/home/lhye200/.octoprint/uploads"
|
||||
|
||||
GCODE_DIR = get_gcode_dir()
|
||||
|
||||
# ── 状态主题色 ──────────────────────────────────────────
|
||||
STATUS_COLORS = {
|
||||
@@ -138,52 +131,6 @@ class TempGauge(QWidget):
|
||||
p.drawText(0, h - 20, w, 20, Qt.AlignmentFlag.AlignCenter, self._label)
|
||||
|
||||
|
||||
# ── GCode 2D 预览(暂注释,待开发)─────────────────────
|
||||
# class GCode2DPreviewWidget(QGraphicsView):
|
||||
# def __init__(self, parent=None):
|
||||
# super().__init__(parent)
|
||||
# self.scene = QGraphicsScene(self)
|
||||
# self.setScene(self.scene)
|
||||
# self.setStyleSheet("background-color: #111111; border-radius: 5px; border: 1px solid #666;")
|
||||
# self.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
# self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
# self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
# self.scale(1, -1)
|
||||
#
|
||||
# def draw_paths(self, lines_data):
|
||||
# self.scene.clear()
|
||||
# bounding_rect = QRectF()
|
||||
# for color_str, data in lines_data.items():
|
||||
# points = data.get("points", [])
|
||||
# line_width = data.get("line_width", 2)
|
||||
# if not points:
|
||||
# continue
|
||||
# path = QPainterPath()
|
||||
# if isinstance(points[0][0], (int, float)):
|
||||
# path.moveTo(float(points[0][0]), float(points[0][1]))
|
||||
# for pt in points[1:]:
|
||||
# path.lineTo(float(pt[0]), float(pt[1]))
|
||||
# else:
|
||||
# for line_pts in points:
|
||||
# if not line_pts:
|
||||
# continue
|
||||
# path.moveTo(float(line_pts[0][0]), float(line_pts[0][1]))
|
||||
# for pt in line_pts[1:]:
|
||||
# path.lineTo(float(pt[0]), float(pt[1]))
|
||||
# path_item = QGraphicsPathItem(path)
|
||||
# pen_color = QColor(color_str) if QColor.isValidColor(color_str) else QColor("white")
|
||||
# pen = QPen(pen_color)
|
||||
# pen.setWidth(int(line_width))
|
||||
# pen.setCosmetic(True)
|
||||
# path_item.setPen(pen)
|
||||
# self.scene.addItem(path_item)
|
||||
# bounding_rect = bounding_rect.united(path.boundingRect())
|
||||
# if bounding_rect.width() < 1 or bounding_rect.height() < 1:
|
||||
# bounding_rect = QRectF(0, 0, 220, 220)
|
||||
# bounding_rect.adjust(-10, -10, 10, 10)
|
||||
# self.scene.setSceneRect(bounding_rect)
|
||||
# self.fitInView(self.scene.sceneRect(), Qt.AspectRatioMode.KeepAspectRatio)
|
||||
|
||||
|
||||
# ── 状态页面 ────────────────────────────────────────────
|
||||
class StatusPage(QWidget):
|
||||
@@ -193,6 +140,7 @@ class StatusPage(QWidget):
|
||||
|
||||
self.file_name = "None"
|
||||
self.progress = 0.0
|
||||
self.filepos = 0
|
||||
self.display_name = "None"
|
||||
self.state = "Unknown"
|
||||
self.print_time = 0
|
||||
@@ -205,6 +153,7 @@ class StatusPage(QWidget):
|
||||
self.config_parser = ConfigParse()
|
||||
self.config_parser.config_changed.connect(self._on_config_changed)
|
||||
self.gcode_dir = self.config_parser.gcode_dir
|
||||
self._loaded_file = None
|
||||
|
||||
self.init_ui()
|
||||
self.timer = QTimer(self)
|
||||
@@ -222,6 +171,7 @@ class StatusPage(QWidget):
|
||||
job = data.get("job", {})
|
||||
self.file_name = job.get("job", {}).get("file", {}).get("name", "None")
|
||||
self.progress = job.get("progress", {}).get("completion", 0) or 0
|
||||
self.filepos = job.get("progress", {}).get("filepos", 0) or 0
|
||||
self.display_name = job.get("job", {}).get("file", {}).get("display_name", "None")
|
||||
self.state = status.get("state", {}).get("text", "Offline")
|
||||
self.print_time = job.get("progress", {}).get("printTime", 0) or 0
|
||||
@@ -336,10 +286,8 @@ class StatusPage(QWidget):
|
||||
right_layout = QVBoxLayout(right_frame)
|
||||
right_layout.setContentsMargins(6, 6, 6, 6)
|
||||
|
||||
placeholder = QLabel("GCode 预览\n⚙ 待开发")
|
||||
placeholder.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
placeholder.setStyleSheet("color: #666666; font-size: 24px; font-weight: 600; border: none;")
|
||||
right_layout.addWidget(placeholder)
|
||||
self.gcode_viewer = GCodeViewerWidget()
|
||||
right_layout.addWidget(self.gcode_viewer)
|
||||
|
||||
main_layout.addWidget(left_frame, 2)
|
||||
main_layout.addWidget(right_frame, 3)
|
||||
@@ -405,6 +353,22 @@ class StatusPage(QWidget):
|
||||
self._tool_gauge.set_value(self.tool_temp_actual, self.tool_temp_target)
|
||||
self._bed_gauge.set_value(self.bed_temp_actual, self.bed_temp_target)
|
||||
|
||||
# G-code 模型加载与进度更新
|
||||
if self.file_name and self.file_name != "None":
|
||||
if self.file_name != self._loaded_file:
|
||||
gcode_path = os.path.join(self.gcode_dir, self.file_name)
|
||||
if os.path.exists(gcode_path):
|
||||
try:
|
||||
self.gcode_viewer.load_gcode(gcode_path)
|
||||
self._loaded_file = self.file_name
|
||||
except Exception as e:
|
||||
print("Failed to load G-code:", e)
|
||||
|
||||
# 使用 filepos 替代进度百分比进行精准的偏移量层级更新
|
||||
if self._loaded_file == self.file_name:
|
||||
is_printing = self.state.startswith("Printing") or self.state.startswith("Paused")
|
||||
self.gcode_viewer.update_by_filepos(self.filepos, is_printing)
|
||||
|
||||
|
||||
|
||||
#TODO: Better Gcode Parser, this one is too slow for large files, need to optimize or use a separate thread to load
|
||||
|
||||
Reference in New Issue
Block a user