|
|
|
@ -1,10 +1,78 @@
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
|
|
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
|
|
QPushButton, QLineEdit, QComboBox)
|
|
|
|
QPushButton, QLineEdit, QComboBox, QApplication)
|
|
|
|
|
|
|
|
from PyQt6.QtGui import QFont
|
|
|
|
from PyQt6.QtCore import pyqtSignal
|
|
|
|
from PyQt6.QtCore import pyqtSignal
|
|
|
|
import glob
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_font_scale():
|
|
|
|
|
|
|
|
app = QApplication.instance()
|
|
|
|
|
|
|
|
if app is None:
|
|
|
|
|
|
|
|
return 1.0
|
|
|
|
|
|
|
|
scale = app.property("font_scale")
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
return float(scale) if scale is not None else 1.0
|
|
|
|
|
|
|
|
except (TypeError, ValueError):
|
|
|
|
|
|
|
|
return 1.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _scale_stylesheet_font_sizes(stylesheet, scale):
|
|
|
|
|
|
|
|
if not stylesheet or 'font-size' not in stylesheet:
|
|
|
|
|
|
|
|
return stylesheet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def repl(match):
|
|
|
|
|
|
|
|
size = float(match.group(1))
|
|
|
|
|
|
|
|
unit = match.group(2)
|
|
|
|
|
|
|
|
scaled = max(1.0, size * scale)
|
|
|
|
|
|
|
|
text = f"{scaled:.2f}".rstrip('0').rstrip('.')
|
|
|
|
|
|
|
|
return f"font-size: {text}{unit}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return re.sub(r'font-size\s*:\s*([0-9]+(?:\.[0-9]+)?)\s*(px|pt)', repl, stylesheet)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _set_scaled_stylesheet(widget, stylesheet):
|
|
|
|
|
|
|
|
widget._base_stylesheet = stylesheet
|
|
|
|
|
|
|
|
scaled = _scale_stylesheet_font_sizes(stylesheet, _get_font_scale())
|
|
|
|
|
|
|
|
widget._applied_stylesheet = scaled
|
|
|
|
|
|
|
|
widget.setStyleSheet(scaled)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _reapply_scaled_stylesheet(widget):
|
|
|
|
|
|
|
|
current_stylesheet = widget.styleSheet()
|
|
|
|
|
|
|
|
base_stylesheet = getattr(widget, '_base_stylesheet', None)
|
|
|
|
|
|
|
|
applied_stylesheet = getattr(widget, '_applied_stylesheet', None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if current_stylesheet != applied_stylesheet:
|
|
|
|
|
|
|
|
base_stylesheet = current_stylesheet
|
|
|
|
|
|
|
|
widget._base_stylesheet = base_stylesheet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if base_stylesheet is not None:
|
|
|
|
|
|
|
|
scaled = _scale_stylesheet_font_sizes(base_stylesheet, _get_font_scale())
|
|
|
|
|
|
|
|
widget._applied_stylesheet = scaled
|
|
|
|
|
|
|
|
if current_stylesheet != scaled:
|
|
|
|
|
|
|
|
widget.setStyleSheet(scaled)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _apply_scaled_font(widget):
|
|
|
|
|
|
|
|
base_font = getattr(widget, '_base_font_for_scale', None)
|
|
|
|
|
|
|
|
if base_font is None:
|
|
|
|
|
|
|
|
app = QApplication.instance()
|
|
|
|
|
|
|
|
app_base_font = app.property("base_app_font") if app else None
|
|
|
|
|
|
|
|
base_font = QFont(app_base_font) if app_base_font is not None else QFont(widget.font())
|
|
|
|
|
|
|
|
widget._base_font_for_scale = QFont(base_font)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scaled_font = QFont(base_font)
|
|
|
|
|
|
|
|
scale = _get_font_scale()
|
|
|
|
|
|
|
|
if base_font.pointSizeF() > 0:
|
|
|
|
|
|
|
|
scaled_font.setPointSizeF(max(1.0, base_font.pointSizeF() * scale))
|
|
|
|
|
|
|
|
elif base_font.pointSize() > 0:
|
|
|
|
|
|
|
|
scaled_font.setPointSize(max(1, int(round(base_font.pointSize() * scale))))
|
|
|
|
|
|
|
|
widget.setFont(scaled_font)
|
|
|
|
|
|
|
|
|
|
|
|
class CommPanel(QWidget):
|
|
|
|
class CommPanel(QWidget):
|
|
|
|
"""通讯设置面板类"""
|
|
|
|
"""通讯设置面板类"""
|
|
|
|
|
|
|
|
|
|
|
|
@ -26,6 +94,7 @@ class CommPanel(QWidget):
|
|
|
|
self.ws_connections = []
|
|
|
|
self.ws_connections = []
|
|
|
|
self.serial_connections = []
|
|
|
|
self.serial_connections = []
|
|
|
|
self._init_ui()
|
|
|
|
self._init_ui()
|
|
|
|
|
|
|
|
self.apply_font_scale()
|
|
|
|
|
|
|
|
|
|
|
|
def _init_ui(self):
|
|
|
|
def _init_ui(self):
|
|
|
|
"""初始化UI"""
|
|
|
|
"""初始化UI"""
|
|
|
|
@ -35,7 +104,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# ========== UDP MAVLink 區域 ==========
|
|
|
|
# ========== UDP MAVLink 區域 ==========
|
|
|
|
udp_title = QLabel("UDP")
|
|
|
|
udp_title = QLabel("UDP")
|
|
|
|
udp_title.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(udp_title, """
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
font-size: 14px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: bold;
|
|
|
|
font-weight: bold;
|
|
|
|
@ -60,7 +129,7 @@ class CommPanel(QWidget):
|
|
|
|
self.udp_ip_input = QLineEdit()
|
|
|
|
self.udp_ip_input = QLineEdit()
|
|
|
|
self.udp_ip_input.setText("127.0.0.1")
|
|
|
|
self.udp_ip_input.setText("127.0.0.1")
|
|
|
|
self.udp_ip_input.setPlaceholderText("IP")
|
|
|
|
self.udp_ip_input.setPlaceholderText("IP")
|
|
|
|
self.udp_ip_input.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(self.udp_ip_input, """
|
|
|
|
QLineEdit {
|
|
|
|
QLineEdit {
|
|
|
|
background-color: #333;
|
|
|
|
background-color: #333;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -74,7 +143,7 @@ class CommPanel(QWidget):
|
|
|
|
self.udp_port_input.setText("14550")
|
|
|
|
self.udp_port_input.setText("14550")
|
|
|
|
self.udp_port_input.setPlaceholderText("Port")
|
|
|
|
self.udp_port_input.setPlaceholderText("Port")
|
|
|
|
self.udp_port_input.setFixedWidth(80)
|
|
|
|
self.udp_port_input.setFixedWidth(80)
|
|
|
|
self.udp_port_input.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(self.udp_port_input, """
|
|
|
|
QLineEdit {
|
|
|
|
QLineEdit {
|
|
|
|
background-color: #333;
|
|
|
|
background-color: #333;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -86,7 +155,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
add_udp_btn = QPushButton("添加")
|
|
|
|
add_udp_btn = QPushButton("添加")
|
|
|
|
add_udp_btn.clicked.connect(self._handle_add_udp)
|
|
|
|
add_udp_btn.clicked.connect(self._handle_add_udp)
|
|
|
|
add_udp_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(add_udp_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #4CAF50;
|
|
|
|
background-color: #4CAF50;
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
@ -98,9 +167,13 @@ class CommPanel(QWidget):
|
|
|
|
QPushButton:hover { background-color: #45a049; }
|
|
|
|
QPushButton:hover { background-color: #45a049; }
|
|
|
|
""")
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
add_udp_layout.addWidget(QLabel("IP:", styleSheet="color: #DDD;"))
|
|
|
|
ip_label = QLabel("IP:")
|
|
|
|
|
|
|
|
_set_scaled_stylesheet(ip_label, "color: #DDD;")
|
|
|
|
|
|
|
|
add_udp_layout.addWidget(ip_label)
|
|
|
|
add_udp_layout.addWidget(self.udp_ip_input)
|
|
|
|
add_udp_layout.addWidget(self.udp_ip_input)
|
|
|
|
add_udp_layout.addWidget(QLabel("Port:", styleSheet="color: #DDD;"))
|
|
|
|
port_label = QLabel("Port:")
|
|
|
|
|
|
|
|
_set_scaled_stylesheet(port_label, "color: #DDD;")
|
|
|
|
|
|
|
|
add_udp_layout.addWidget(port_label)
|
|
|
|
add_udp_layout.addWidget(self.udp_port_input)
|
|
|
|
add_udp_layout.addWidget(self.udp_port_input)
|
|
|
|
add_udp_layout.addWidget(add_udp_btn)
|
|
|
|
add_udp_layout.addWidget(add_udp_btn)
|
|
|
|
|
|
|
|
|
|
|
|
@ -113,7 +186,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# ========== Serial 區域 ==========
|
|
|
|
# ========== Serial 區域 ==========
|
|
|
|
serial_title = QLabel("Serial")
|
|
|
|
serial_title = QLabel("Serial")
|
|
|
|
serial_title.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(serial_title, """
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
font-size: 14px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: bold;
|
|
|
|
font-weight: bold;
|
|
|
|
@ -136,7 +209,7 @@ class CommPanel(QWidget):
|
|
|
|
add_serial_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
add_serial_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
self.serial_port_combo = QComboBox()
|
|
|
|
self.serial_port_combo = QComboBox()
|
|
|
|
self.serial_port_combo.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(self.serial_port_combo, """
|
|
|
|
QComboBox {
|
|
|
|
QComboBox {
|
|
|
|
background-color: #333;
|
|
|
|
background-color: #333;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -160,7 +233,7 @@ class CommPanel(QWidget):
|
|
|
|
refresh_ports_btn.setFixedWidth(35)
|
|
|
|
refresh_ports_btn.setFixedWidth(35)
|
|
|
|
refresh_ports_btn.clicked.connect(self._refresh_serial_ports)
|
|
|
|
refresh_ports_btn.clicked.connect(self._refresh_serial_ports)
|
|
|
|
refresh_ports_btn.setToolTip("重新掃描串口")
|
|
|
|
refresh_ports_btn.setToolTip("重新掃描串口")
|
|
|
|
refresh_ports_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(refresh_ports_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #444;
|
|
|
|
background-color: #444;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -176,7 +249,7 @@ class CommPanel(QWidget):
|
|
|
|
self.serial_baudrate_combo.addItems(['9600', '19200', '38400', '57600', '115200'])
|
|
|
|
self.serial_baudrate_combo.addItems(['9600', '19200', '38400', '57600', '115200'])
|
|
|
|
self.serial_baudrate_combo.setCurrentText('57600')
|
|
|
|
self.serial_baudrate_combo.setCurrentText('57600')
|
|
|
|
self.serial_baudrate_combo.setFixedWidth(100)
|
|
|
|
self.serial_baudrate_combo.setFixedWidth(100)
|
|
|
|
self.serial_baudrate_combo.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(self.serial_baudrate_combo, """
|
|
|
|
QComboBox {
|
|
|
|
QComboBox {
|
|
|
|
background-color: #333;
|
|
|
|
background-color: #333;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -197,7 +270,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
add_serial_btn = QPushButton("添加")
|
|
|
|
add_serial_btn = QPushButton("添加")
|
|
|
|
add_serial_btn.clicked.connect(self._handle_add_serial)
|
|
|
|
add_serial_btn.clicked.connect(self._handle_add_serial)
|
|
|
|
add_serial_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(add_serial_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #4CAF50;
|
|
|
|
background-color: #4CAF50;
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
@ -209,10 +282,14 @@ class CommPanel(QWidget):
|
|
|
|
QPushButton:hover { background-color: #45a049; }
|
|
|
|
QPushButton:hover { background-color: #45a049; }
|
|
|
|
""")
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
add_serial_layout.addWidget(QLabel("Port:", styleSheet="color: #DDD;"))
|
|
|
|
serial_port_label = QLabel("Port:")
|
|
|
|
|
|
|
|
_set_scaled_stylesheet(serial_port_label, "color: #DDD;")
|
|
|
|
|
|
|
|
add_serial_layout.addWidget(serial_port_label)
|
|
|
|
add_serial_layout.addWidget(self.serial_port_combo)
|
|
|
|
add_serial_layout.addWidget(self.serial_port_combo)
|
|
|
|
add_serial_layout.addWidget(refresh_ports_btn)
|
|
|
|
add_serial_layout.addWidget(refresh_ports_btn)
|
|
|
|
add_serial_layout.addWidget(QLabel("Baud:", styleSheet="color: #DDD;"))
|
|
|
|
baud_label = QLabel("Baud:")
|
|
|
|
|
|
|
|
_set_scaled_stylesheet(baud_label, "color: #DDD;")
|
|
|
|
|
|
|
|
add_serial_layout.addWidget(baud_label)
|
|
|
|
add_serial_layout.addWidget(self.serial_baudrate_combo)
|
|
|
|
add_serial_layout.addWidget(self.serial_baudrate_combo)
|
|
|
|
add_serial_layout.addWidget(add_serial_btn)
|
|
|
|
add_serial_layout.addWidget(add_serial_btn)
|
|
|
|
|
|
|
|
|
|
|
|
@ -225,7 +302,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# ========== WebSocket 區域 ==========
|
|
|
|
# ========== WebSocket 區域 ==========
|
|
|
|
ws_title = QLabel("WebSocket")
|
|
|
|
ws_title = QLabel("WebSocket")
|
|
|
|
ws_title.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(ws_title, """
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
font-size: 14px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: bold;
|
|
|
|
font-weight: bold;
|
|
|
|
@ -249,7 +326,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
self.ws_url_input = QLineEdit()
|
|
|
|
self.ws_url_input = QLineEdit()
|
|
|
|
self.ws_url_input.setPlaceholderText("host")
|
|
|
|
self.ws_url_input.setPlaceholderText("host")
|
|
|
|
self.ws_url_input.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(self.ws_url_input, """
|
|
|
|
QLineEdit {
|
|
|
|
QLineEdit {
|
|
|
|
background-color: #333;
|
|
|
|
background-color: #333;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -261,7 +338,7 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
add_ws_btn = QPushButton("添加")
|
|
|
|
add_ws_btn = QPushButton("添加")
|
|
|
|
add_ws_btn.clicked.connect(self._handle_add_ws)
|
|
|
|
add_ws_btn.clicked.connect(self._handle_add_ws)
|
|
|
|
add_ws_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(add_ws_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #4CAF50;
|
|
|
|
background-color: #4CAF50;
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
@ -273,7 +350,9 @@ class CommPanel(QWidget):
|
|
|
|
QPushButton:hover { background-color: #45a049; }
|
|
|
|
QPushButton:hover { background-color: #45a049; }
|
|
|
|
""")
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
add_ws_layout.addWidget(QLabel("URL:", styleSheet="color: #DDD;"))
|
|
|
|
url_label = QLabel("URL:")
|
|
|
|
|
|
|
|
_set_scaled_stylesheet(url_label, "color: #DDD;")
|
|
|
|
|
|
|
|
add_ws_layout.addWidget(url_label)
|
|
|
|
add_ws_layout.addWidget(self.ws_url_input)
|
|
|
|
add_ws_layout.addWidget(self.ws_url_input)
|
|
|
|
add_ws_layout.addWidget(add_ws_btn)
|
|
|
|
add_ws_layout.addWidget(add_ws_btn)
|
|
|
|
|
|
|
|
|
|
|
|
@ -437,7 +516,7 @@ class CommPanel(QWidget):
|
|
|
|
def create_udp_connection_panel(self, conn):
|
|
|
|
def create_udp_connection_panel(self, conn):
|
|
|
|
"""創建 UDP 連接面板"""
|
|
|
|
"""創建 UDP 連接面板"""
|
|
|
|
panel = QWidget()
|
|
|
|
panel = QWidget()
|
|
|
|
panel.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(panel, """
|
|
|
|
QWidget {
|
|
|
|
QWidget {
|
|
|
|
background-color: #2A2A2A;
|
|
|
|
background-color: #2A2A2A;
|
|
|
|
border-radius: 6px;
|
|
|
|
border-radius: 6px;
|
|
|
|
@ -451,22 +530,22 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# 連接資訊
|
|
|
|
# 連接資訊
|
|
|
|
info_label = QLabel(f"{conn['name']} - {conn['ip']}:{conn['port']}")
|
|
|
|
info_label = QLabel(f"{conn['name']} - {conn['ip']}:{conn['port']}")
|
|
|
|
info_label.setStyleSheet("color: #DDD; font-size: 12px;")
|
|
|
|
_set_scaled_stylesheet(info_label, "color: #DDD; font-size: 12px;")
|
|
|
|
|
|
|
|
|
|
|
|
# 狀態指示器
|
|
|
|
# 狀態指示器
|
|
|
|
status_label = QLabel("●")
|
|
|
|
status_label = QLabel("●")
|
|
|
|
if conn.get('enabled', False):
|
|
|
|
if conn.get('enabled', False):
|
|
|
|
status_label.setStyleSheet("color: #4CAF50; font-size: 16px;")
|
|
|
|
_set_scaled_stylesheet(status_label, "color: #4CAF50; font-size: 16px;")
|
|
|
|
status_label.setToolTip("運行中")
|
|
|
|
status_label.setToolTip("運行中")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
status_label.setStyleSheet("color: #888; font-size: 16px;")
|
|
|
|
_set_scaled_stylesheet(status_label, "color: #888; font-size: 16px;")
|
|
|
|
status_label.setToolTip("已停止")
|
|
|
|
status_label.setToolTip("已停止")
|
|
|
|
|
|
|
|
|
|
|
|
# 控制按鈕
|
|
|
|
# 控制按鈕
|
|
|
|
toggle_btn = QPushButton("停止" if conn.get('enabled', False) else "啟動")
|
|
|
|
toggle_btn = QPushButton("停止" if conn.get('enabled', False) else "啟動")
|
|
|
|
toggle_btn.setFixedWidth(60)
|
|
|
|
toggle_btn.setFixedWidth(60)
|
|
|
|
toggle_btn.clicked.connect(lambda: self.udp_connection_toggled.emit(conn, toggle_btn, status_label))
|
|
|
|
toggle_btn.clicked.connect(lambda: self.udp_connection_toggled.emit(conn, toggle_btn, status_label))
|
|
|
|
toggle_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(toggle_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #444;
|
|
|
|
background-color: #444;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -481,7 +560,7 @@ class CommPanel(QWidget):
|
|
|
|
remove_btn = QPushButton("移除")
|
|
|
|
remove_btn = QPushButton("移除")
|
|
|
|
remove_btn.setFixedWidth(60)
|
|
|
|
remove_btn.setFixedWidth(60)
|
|
|
|
remove_btn.clicked.connect(lambda: self.udp_connection_removed.emit(conn, panel))
|
|
|
|
remove_btn.clicked.connect(lambda: self.udp_connection_removed.emit(conn, panel))
|
|
|
|
remove_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(remove_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #d32f2f;
|
|
|
|
background-color: #d32f2f;
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
@ -509,7 +588,7 @@ class CommPanel(QWidget):
|
|
|
|
def create_ws_connection_panel(self, conn):
|
|
|
|
def create_ws_connection_panel(self, conn):
|
|
|
|
"""創建 WebSocket 連接面板"""
|
|
|
|
"""創建 WebSocket 連接面板"""
|
|
|
|
panel = QWidget()
|
|
|
|
panel = QWidget()
|
|
|
|
panel.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(panel, """
|
|
|
|
QWidget {
|
|
|
|
QWidget {
|
|
|
|
background-color: #2A2A2A;
|
|
|
|
background-color: #2A2A2A;
|
|
|
|
border-radius: 6px;
|
|
|
|
border-radius: 6px;
|
|
|
|
@ -523,22 +602,22 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# 連接資訊
|
|
|
|
# 連接資訊
|
|
|
|
info_label = QLabel(f"{conn['name']} - {conn['url']}")
|
|
|
|
info_label = QLabel(f"{conn['name']} - {conn['url']}")
|
|
|
|
info_label.setStyleSheet("color: #DDD; font-size: 12px;")
|
|
|
|
_set_scaled_stylesheet(info_label, "color: #DDD; font-size: 12px;")
|
|
|
|
|
|
|
|
|
|
|
|
# 狀態指示器
|
|
|
|
# 狀態指示器
|
|
|
|
status_label = QLabel("●")
|
|
|
|
status_label = QLabel("●")
|
|
|
|
if conn.get('enabled', False):
|
|
|
|
if conn.get('enabled', False):
|
|
|
|
status_label.setStyleSheet("color: #4CAF50; font-size: 16px;")
|
|
|
|
_set_scaled_stylesheet(status_label, "color: #4CAF50; font-size: 16px;")
|
|
|
|
status_label.setToolTip("運行中")
|
|
|
|
status_label.setToolTip("運行中")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
status_label.setStyleSheet("color: #888; font-size: 16px;")
|
|
|
|
_set_scaled_stylesheet(status_label, "color: #888; font-size: 16px;")
|
|
|
|
status_label.setToolTip("已停止")
|
|
|
|
status_label.setToolTip("已停止")
|
|
|
|
|
|
|
|
|
|
|
|
# 控制按鈕
|
|
|
|
# 控制按鈕
|
|
|
|
toggle_btn = QPushButton("停止" if conn.get('enabled', False) else "啟動")
|
|
|
|
toggle_btn = QPushButton("停止" if conn.get('enabled', False) else "啟動")
|
|
|
|
toggle_btn.setFixedWidth(60)
|
|
|
|
toggle_btn.setFixedWidth(60)
|
|
|
|
toggle_btn.clicked.connect(lambda: self.ws_connection_toggled.emit(conn, toggle_btn, status_label))
|
|
|
|
toggle_btn.clicked.connect(lambda: self.ws_connection_toggled.emit(conn, toggle_btn, status_label))
|
|
|
|
toggle_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(toggle_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #444;
|
|
|
|
background-color: #444;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -553,7 +632,7 @@ class CommPanel(QWidget):
|
|
|
|
remove_btn = QPushButton("移除")
|
|
|
|
remove_btn = QPushButton("移除")
|
|
|
|
remove_btn.setFixedWidth(60)
|
|
|
|
remove_btn.setFixedWidth(60)
|
|
|
|
remove_btn.clicked.connect(lambda: self.ws_connection_removed.emit(conn, panel))
|
|
|
|
remove_btn.clicked.connect(lambda: self.ws_connection_removed.emit(conn, panel))
|
|
|
|
remove_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(remove_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #d32f2f;
|
|
|
|
background-color: #d32f2f;
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
@ -605,7 +684,7 @@ class CommPanel(QWidget):
|
|
|
|
def create_serial_connection_panel(self, conn):
|
|
|
|
def create_serial_connection_panel(self, conn):
|
|
|
|
"""創建 Serial 連接面板"""
|
|
|
|
"""創建 Serial 連接面板"""
|
|
|
|
panel = QWidget()
|
|
|
|
panel = QWidget()
|
|
|
|
panel.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(panel, """
|
|
|
|
QWidget {
|
|
|
|
QWidget {
|
|
|
|
background-color: #2A2A2A;
|
|
|
|
background-color: #2A2A2A;
|
|
|
|
border-radius: 6px;
|
|
|
|
border-radius: 6px;
|
|
|
|
@ -619,22 +698,22 @@ class CommPanel(QWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# 連接資訊
|
|
|
|
# 連接資訊
|
|
|
|
info_label = QLabel(f"{conn['name']} - {conn['port']} @ {conn['baudrate']}")
|
|
|
|
info_label = QLabel(f"{conn['name']} - {conn['port']} @ {conn['baudrate']}")
|
|
|
|
info_label.setStyleSheet("color: #DDD; font-size: 12px;")
|
|
|
|
_set_scaled_stylesheet(info_label, "color: #DDD; font-size: 12px;")
|
|
|
|
|
|
|
|
|
|
|
|
# 狀態指示器
|
|
|
|
# 狀態指示器
|
|
|
|
status_label = QLabel("●")
|
|
|
|
status_label = QLabel("●")
|
|
|
|
if conn.get('enabled', False):
|
|
|
|
if conn.get('enabled', False):
|
|
|
|
status_label.setStyleSheet("color: #4CAF50; font-size: 16px;")
|
|
|
|
_set_scaled_stylesheet(status_label, "color: #4CAF50; font-size: 16px;")
|
|
|
|
status_label.setToolTip("運行中")
|
|
|
|
status_label.setToolTip("運行中")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
status_label.setStyleSheet("color: #888; font-size: 16px;")
|
|
|
|
_set_scaled_stylesheet(status_label, "color: #888; font-size: 16px;")
|
|
|
|
status_label.setToolTip("已停止")
|
|
|
|
status_label.setToolTip("已停止")
|
|
|
|
|
|
|
|
|
|
|
|
# 控制按鈕
|
|
|
|
# 控制按鈕
|
|
|
|
toggle_btn = QPushButton("停止" if conn.get('enabled', False) else "啟動")
|
|
|
|
toggle_btn = QPushButton("停止" if conn.get('enabled', False) else "啟動")
|
|
|
|
toggle_btn.setFixedWidth(60)
|
|
|
|
toggle_btn.setFixedWidth(60)
|
|
|
|
toggle_btn.clicked.connect(lambda: self.serial_connection_toggled.emit(conn, toggle_btn, status_label))
|
|
|
|
toggle_btn.clicked.connect(lambda: self.serial_connection_toggled.emit(conn, toggle_btn, status_label))
|
|
|
|
toggle_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(toggle_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #444;
|
|
|
|
background-color: #444;
|
|
|
|
color: #DDD;
|
|
|
|
color: #DDD;
|
|
|
|
@ -649,7 +728,7 @@ class CommPanel(QWidget):
|
|
|
|
remove_btn = QPushButton("移除")
|
|
|
|
remove_btn = QPushButton("移除")
|
|
|
|
remove_btn.setFixedWidth(60)
|
|
|
|
remove_btn.setFixedWidth(60)
|
|
|
|
remove_btn.clicked.connect(lambda: self.serial_connection_removed.emit(conn, panel))
|
|
|
|
remove_btn.clicked.connect(lambda: self.serial_connection_removed.emit(conn, panel))
|
|
|
|
remove_btn.setStyleSheet("""
|
|
|
|
_set_scaled_stylesheet(remove_btn, """
|
|
|
|
QPushButton {
|
|
|
|
QPushButton {
|
|
|
|
background-color: #d32f2f;
|
|
|
|
background-color: #d32f2f;
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
@ -685,3 +764,11 @@ class CommPanel(QWidget):
|
|
|
|
"""從列表中移除 Serial 連接"""
|
|
|
|
"""從列表中移除 Serial 連接"""
|
|
|
|
if conn in self.serial_connections:
|
|
|
|
if conn in self.serial_connections:
|
|
|
|
self.serial_connections.remove(conn)
|
|
|
|
self.serial_connections.remove(conn)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def apply_font_scale(self):
|
|
|
|
|
|
|
|
"""重新套用目前字體倍率到通訊面板。"""
|
|
|
|
|
|
|
|
_apply_scaled_font(self)
|
|
|
|
|
|
|
|
_reapply_scaled_stylesheet(self)
|
|
|
|
|
|
|
|
for child in self.findChildren(QWidget):
|
|
|
|
|
|
|
|
_apply_scaled_font(child)
|
|
|
|
|
|
|
|
_reapply_scaled_stylesheet(child)
|
|
|
|
|