터치 패널 관찰 전용 슬라이더와 이중 축 개선
This commit is contained in:
1 parent
e0b384838d
commit
6aa8e7277f
2 files changed
+29
-72
No files matched your search
+27
-70
@@ -14,7 +14,6 @@ from PyQt5.QtWidgets import (
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QMainWindow,
|
||||
QPushButton,
|
||||
QSlider,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
@@ -129,16 +128,6 @@ def disk_io():
|
||||
return reads, writes, not found
|
||||
|
||||
|
||||
def write_sys(path, value):
|
||||
if not path:
|
||||
return False
|
||||
try:
|
||||
Path(path).write_text(str(value) + "\n", encoding="utf-8")
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def send_magic_packet(mac):
|
||||
clean = mac.replace(":", "").replace("-", "")
|
||||
if len(clean) != 12:
|
||||
@@ -167,7 +156,7 @@ class StatusDot(QWidget):
|
||||
self.update()
|
||||
|
||||
def blink(self):
|
||||
self.pulse = 3
|
||||
self.pulse = 1
|
||||
self.update()
|
||||
|
||||
def tick(self):
|
||||
@@ -284,12 +273,13 @@ class MetricCard(QFrame):
|
||||
|
||||
|
||||
class Sparkline(QFrame):
|
||||
def __init__(self, title, color="#38bdf8", second_color=None, y_unit=""):
|
||||
def __init__(self, title, color="#38bdf8", second_color=None, y_unit="", right_unit=""):
|
||||
super().__init__()
|
||||
self.setObjectName("chartCard")
|
||||
self.color = QColor(color)
|
||||
self.second_color = QColor(second_color) if second_color else None
|
||||
self.y_unit = y_unit
|
||||
self.right_unit = right_unit
|
||||
self.values = []
|
||||
self.second_values = []
|
||||
self.title = QLabel(title)
|
||||
@@ -320,15 +310,15 @@ class Sparkline(QFrame):
|
||||
del event
|
||||
painter = QPainter(self.canvas)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
rect = self.canvas.rect().adjusted(34, 4, -2, -13)
|
||||
right_margin = 34 if self.second_values and self.right_unit else 2
|
||||
rect = self.canvas.rect().adjusted(34, 4, -right_margin, -13)
|
||||
painter.fillRect(rect, QColor("#0f172a"))
|
||||
painter.setPen(QPen(QColor("#263650"), 1))
|
||||
painter.drawLine(rect.left(), rect.bottom(), rect.right(), rect.bottom())
|
||||
all_values = self.values + self.second_values
|
||||
if len(all_values) < 2:
|
||||
if len(self.values) < 2:
|
||||
return
|
||||
low = min(all_values)
|
||||
high = max(all_values)
|
||||
low = min(self.values)
|
||||
high = max(self.values)
|
||||
if high <= low:
|
||||
high = low + 1
|
||||
painter.setPen(QColor("#93a4bd"))
|
||||
@@ -336,16 +326,25 @@ class Sparkline(QFrame):
|
||||
painter.drawText(1, rect.bottom(), self.axis_text(low))
|
||||
self.draw_series(painter, rect, self.values, low, high, self.color)
|
||||
if self.second_color and self.second_values:
|
||||
self.draw_series(painter, rect, self.second_values, low, high, self.second_color)
|
||||
second_low = min(self.second_values)
|
||||
second_high = max(self.second_values)
|
||||
if second_high <= second_low:
|
||||
second_high = second_low + 1
|
||||
if self.right_unit:
|
||||
painter.setPen(QColor("#93a4bd"))
|
||||
right_x = self.canvas.rect().right() - 31
|
||||
painter.drawText(right_x, rect.top() + 10, self.axis_text(second_high, self.right_unit))
|
||||
painter.drawText(right_x, rect.bottom(), self.axis_text(second_low, self.right_unit))
|
||||
self.draw_series(painter, rect, self.second_values, second_low, second_high, self.second_color)
|
||||
|
||||
def axis_text(self, value):
|
||||
def axis_text(self, value, unit=None):
|
||||
if abs(value) >= 100:
|
||||
text = f"{value:.0f}"
|
||||
elif abs(value) >= 10:
|
||||
text = f"{value:.1f}"
|
||||
else:
|
||||
text = f"{value:.2f}"
|
||||
return f"{text}{self.y_unit}"
|
||||
return f"{text}{self.y_unit if unit is None else unit}"
|
||||
|
||||
@staticmethod
|
||||
def draw_series(painter, rect, values, low, high, color):
|
||||
@@ -365,7 +364,6 @@ class TouchPanel(QMainWindow):
|
||||
self.rows = {}
|
||||
self.metrics = {}
|
||||
self.charts = {}
|
||||
self.mode_buttons = {}
|
||||
self.fan = fan_paths()
|
||||
self.wan_iface = default_iface()
|
||||
NET_GROUPS["wan"] = [self.wan_iface]
|
||||
@@ -403,7 +401,7 @@ class TouchPanel(QMainWindow):
|
||||
self.disk_temp_proc.finished.connect(self.disk_temp_finished)
|
||||
self.disk_temp_timer = QTimer(self)
|
||||
self.disk_temp_timer.timeout.connect(self.update_disk_temp)
|
||||
self.disk_temp_timer.start(5000)
|
||||
self.disk_temp_timer.start(1000)
|
||||
|
||||
self.pulse_timer = QTimer(self)
|
||||
self.pulse_timer.timeout.connect(self.tick_pulses)
|
||||
@@ -463,37 +461,20 @@ class TouchPanel(QMainWindow):
|
||||
metric_grid.addWidget(card, 0, index)
|
||||
right_layout.addLayout(metric_grid)
|
||||
|
||||
mode_layout = QHBoxLayout()
|
||||
for mode, label in [("auto", "auto"), ("manual", "manual"), ("off", "off")]:
|
||||
btn = QPushButton(label)
|
||||
btn.setCheckable(True)
|
||||
btn.clicked.connect(lambda checked=False, m=mode: self.set_fan(m))
|
||||
self.mode_buttons[mode] = btn
|
||||
mode_layout.addWidget(btn)
|
||||
right_layout.addLayout(mode_layout)
|
||||
|
||||
slider_wrap = QHBoxLayout()
|
||||
minus = QPushButton("-")
|
||||
minus.setObjectName("stepButton")
|
||||
minus.clicked.connect(lambda: self.step_pwm(-10))
|
||||
plus = QPushButton("+")
|
||||
plus.setObjectName("stepButton")
|
||||
plus.clicked.connect(lambda: self.step_pwm(10))
|
||||
self.slider = QSlider(Qt.Horizontal)
|
||||
self.slider.setRange(0, 255)
|
||||
self.slider.setValue(self.current_pwm)
|
||||
self.slider.valueChanged.connect(self.slider_changed)
|
||||
self.slider.sliderReleased.connect(lambda: self.set_fan("manual"))
|
||||
slider_wrap.addWidget(minus)
|
||||
self.slider.setFocusPolicy(Qt.NoFocus)
|
||||
self.slider.setAttribute(Qt.WA_TransparentForMouseEvents, True)
|
||||
slider_wrap.addWidget(self.slider, 1)
|
||||
slider_wrap.addWidget(plus)
|
||||
right_layout.addLayout(slider_wrap)
|
||||
|
||||
chart_grid = QGridLayout()
|
||||
chart_grid.setHorizontalSpacing(8)
|
||||
chart_grid.setVerticalSpacing(8)
|
||||
for index, (key, chart) in enumerate([
|
||||
("temp", Sparkline("온도 / RPM", "#f97316", "#38bdf8", "C")),
|
||||
("temp", Sparkline("온도 / RPM", "#f97316", "#38bdf8", "C", "rpm")),
|
||||
("wan", Sparkline("WAN 트래픽", "#38bdf8", "#22c55e", "M")),
|
||||
]):
|
||||
self.charts[key] = chart
|
||||
@@ -558,9 +539,7 @@ class TouchPanel(QMainWindow):
|
||||
self.slider.blockSignals(True)
|
||||
self.slider.setValue(pwm)
|
||||
self.slider.blockSignals(False)
|
||||
self.mode_buttons["off"].setChecked(enable == 0 or pwm == 0)
|
||||
self.mode_buttons["manual"].setChecked(enable == 1 and pwm > 0)
|
||||
self.mode_buttons["auto"].setChecked(enable not in [0, 1])
|
||||
del enable
|
||||
|
||||
self.clock.setText(time.strftime("%H:%M:%S"))
|
||||
self.latest_temp = temp
|
||||
@@ -595,8 +574,8 @@ class TouchPanel(QMainWindow):
|
||||
temp = getattr(self, "latest_temp", cpu_temp())
|
||||
rpm = getattr(self, "latest_rpm", read_int(self.fan["rpm"]))
|
||||
self.temp_history.append(temp)
|
||||
self.rpm_history.append(rpm / 100)
|
||||
self.charts["temp"].set_values(self.temp_history, "C / RPMx100", self.rpm_history)
|
||||
self.rpm_history.append(rpm)
|
||||
self.charts["temp"].set_values(self.temp_history, "C / RPM", self.rpm_history)
|
||||
|
||||
wan = self.current_rates.get("wan", {"rx": 0.0, "tx": 0.0})
|
||||
self.net_history["wan"]["rx"].append(wan["rx"])
|
||||
@@ -607,25 +586,6 @@ class TouchPanel(QMainWindow):
|
||||
self.net_history["wan"]["tx"],
|
||||
)
|
||||
|
||||
def set_fan(self, mode):
|
||||
pwm = self.slider.value()
|
||||
ok = True
|
||||
if mode == "off":
|
||||
ok = write_sys(self.fan["enable"], 0) and write_sys(self.fan["pwm"], 0)
|
||||
elif mode == "manual":
|
||||
ok = write_sys(self.fan["enable"], 1) and write_sys(self.fan["pwm"], pwm)
|
||||
elif mode == "auto":
|
||||
ok = write_sys(self.fan["enable"], 2)
|
||||
self.status_text.setText("" if ok else "팬 쓰기 권한 없음")
|
||||
|
||||
def step_pwm(self, delta):
|
||||
self.slider.setValue(max(0, min(255, self.slider.value() + delta)))
|
||||
self.set_fan("manual")
|
||||
|
||||
def slider_changed(self, value):
|
||||
self.current_pwm = value
|
||||
self.metrics["pwm"].set_value(f"{value} / {value / 255 * 100:.1f}%")
|
||||
|
||||
def tick_pulses(self):
|
||||
for row in self.rows.values():
|
||||
row.tick()
|
||||
@@ -662,9 +622,6 @@ def main():
|
||||
#chartCaption { color: #93a4bd; font-size: 11px; background: transparent; }
|
||||
#clock { font-size: 18px; color: #8fb3ff; font-weight: 700; }
|
||||
#statusText { color: #93a4bd; font-size: 13px; background: transparent; }
|
||||
QPushButton { min-height: 42px; border: 1px solid #33445f; border-radius: 14px; background: #1a2942; color: #dce8f8; font-size: 18px; font-weight: 700; }
|
||||
QPushButton:checked { background: #16a34a; color: white; border-color: #22c55e; }
|
||||
QPushButton#stepButton { min-width: 56px; font-size: 28px; }
|
||||
QSlider::groove:horizontal { height: 10px; background: #263650; border-radius: 5px; }
|
||||
QSlider::sub-page:horizontal { background: #22c55e; border-radius: 5px; }
|
||||
QSlider::handle:horizontal { width: 28px; margin: -10px 0; border-radius: 14px; background: #f8fafc; }
|
||||
|
||||
Reference in new issue
Block a user