Files
AIO_3D_Print_Local_Screen/main.py
2026-05-11 00:21:16 +08:00

208 lines
7.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import os
import json
import time
from datetime import datetime
from PyQt6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QLabel, QStackedWidget)
from PyQt6.QtCore import Qt, QSize, QTimer
from PyQt6.QtGui import QIcon, QFont
from pages.status_page import StatusPage
from pages.control_page import ControlPage
from pages.setting_page import SettingPage
from utils.aio_print_api import AIOPrrintSystemAPI
from utils.auto_fan_status import AutoFanStatus
from utils.config_parse import ConfigParse
from utils.wifi_manager import WifiManager
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 初始化 API 客户端
self.config_parser = ConfigParse()
self.config_parser.config_changed.connect(self._on_config_changed)
self.api_client = AIOPrrintSystemAPI(
api_url=self.config_parser.api_url,
api_key=self.config_parser.api_key
)
self.auto_fan_status = AutoFanStatus()
self.wifi_manager = WifiManager()
self._last_network_check = 0.0
self._is_network_connected = False
self.init_ui()
# 定时刷新风扇状态显示
self._fan_timer = QTimer(self)
self._fan_timer.timeout.connect(self._update_top_bar)
self._fan_timer.start(1000)
def _check_network(self):
"""检查网络连接状态每30秒检测一次避免频繁调用"""
now = time.time()
if now - self._last_network_check < 30:
return self._is_network_connected
self._last_network_check = now
try:
status = self.wifi_manager.get_current_status()
self._is_network_connected = status.get("wpa_state") == "COMPLETED"
except Exception:
self._is_network_connected = False
return self._is_network_connected
def _on_config_changed(self, config_instance):
"""配置变化时更新 API 客户端等相关设置"""
self.api_client = AIOPrrintSystemAPI(
api_url=self.config_parser.api_url,
api_key=self.config_parser.api_key
)
def _update_top_bar(self):
"""更新风扇状态横条显示"""
s = self.auto_fan_status
temp = f"{s.cpu_temp:.1f}°C" if s.is_auto_fan_service_running else "--.-°C"
speed_pct = min(s.fan_speed / 255 * 100, 100)
speed = f"{speed_pct:.1f}%" if s.is_auto_fan_service_running else "--.-%"
state = s.fan_state if s.is_auto_fan_service_running else "Auto Fan service is not running"
rpm = f"{s.fan_rpm:.1f} r/min" if s.is_auto_fan_service_running else "--.-- r/min"
# 根据运行状态改变颜色
if s.is_auto_fan_service_running:
if s.fan_state == "Stalled":
color = "#e86c60" # 风扇异常-红色
else:
color = "#a0d8a0" # 正常-浅绿色
else:
color = "#e8a060" # 异常-橙色
self._top_bar.setStyleSheet(
f"background-color: #2a2a2a; color: {color}; "
f"font-size: 18px; font-weight: 600; padding: 4px 16px;"
)
self._fan_label.setText(
f"🌡 {temp} {state} 𖣘 {speed} {rpm}"
)
# 更新时钟(有网络时显示)
if self._check_network():
now = datetime.now()
self._clock_label.setText(now.strftime("%H:%M:%S"))
self._clock_label.show()
else:
self._clock_label.hide()
def init_ui(self):
# 整体布局
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# 顶部主显示区 (使用 QStackedWidget 切换不同页面)
self.stacked_widget = QStackedWidget()
self.stacked_widget.setStyleSheet("background-color: #555555;") # 深灰色主显示区
# 添加测试页面
self.page_status = StatusPage(self.api_client)
self.page_control = ControlPage(self.api_client)
self.page_settings = SettingPage(self.api_client)
self.stacked_widget.addWidget(self.page_status)
self.stacked_widget.addWidget(self.page_control)
self.stacked_widget.addWidget(self.page_settings)
# 风扇状态横条
self._top_bar = QWidget()
self._top_bar.setFixedHeight(36)
self._top_bar.setStyleSheet(
"background-color: #2a2a2a; color: #a0d8a0; "
"font-size: 18px; font-weight: 600; padding: 4px 16px;"
)
top_layout = QHBoxLayout(self._top_bar)
top_layout.setContentsMargins(16, 0, 16, 0)
self._fan_label = QLabel("🌡 --°C -- 𖣘 --% -- r/min")
self._fan_label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
top_layout.addWidget(self._fan_label)
top_layout.addStretch()
# 时钟标签(有网络时显示)
self._clock_label = QLabel("--:--:--")
self._clock_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._clock_label.setStyleSheet("color: #a0d8a0; font-size: 18px; font-weight: 600;")
self._clock_label.hide()
top_layout.addWidget(self._clock_label)
# 底部按钮区
bottom_layout = QHBoxLayout()
bottom_layout.setContentsMargins(10, 10, 10, 10)
bottom_layout.setSpacing(20)
# 定义底部区域背景
bottom_widget = QWidget()
bottom_widget.setStyleSheet("background-color: #333333;")
bottom_widget.setLayout(bottom_layout)
bottom_widget.setFixedHeight(120) # 为触摸优化的按钮高度
# 创建触摸友好的按钮
self.btn_status = self.create_nav_button("状态", self.switchToStatus)
self.btn_control = self.create_nav_button("控制", self.switchToControl)
self.btn_settings = self.create_nav_button("设置", self.switchToSettings)
bottom_layout.addWidget(self.btn_status)
bottom_layout.addWidget(self.btn_control)
bottom_layout.addWidget(self.btn_settings)
# 将主显示区、风扇横条、底部按钮加入整体布局
main_layout.addWidget(self._top_bar)
main_layout.addWidget(self.stacked_widget)
main_layout.addWidget(bottom_widget)
self.setLayout(main_layout)
self.setStyleSheet("background-color: #666666;") # 整体灰色背景
def create_nav_button(self, text, callback):
# 如果有图标,可以使用 btn.setIcon(QIcon("path/to/icon.png"))
btn = QPushButton(text)
# 为触摸屏优化:大字体,增加内边距
btn.setStyleSheet("""
QPushButton {
background-color: #444444;
color: white;
border: 2px solid #555555;
border-radius: 10px;
font-size: 32px;
padding: 10px;
}
QPushButton:pressed {
background-color: #222222;
border: 2px solid #4CAF50;
}
""")
btn.setSizePolicy(btn.sizePolicy().Policy.Expanding, btn.sizePolicy().Policy.Expanding)
btn.clicked.connect(callback)
return btn
def switchToStatus(self):
self.stacked_widget.setCurrentIndex(0)
def switchToControl(self):
self.stacked_widget.setCurrentIndex(1)
def switchToSettings(self):
self.stacked_widget.setCurrentIndex(2)
def main():
app = QApplication(sys.argv)
# 隐藏鼠标光标,针对触摸屏优化
app.setOverrideCursor(Qt.CursorShape.BlankCursor)
window = MainWindow()
# 全屏无边框显示
window.showFullScreen()
sys.exit(app.exec())
if __name__ == "__main__":
main()