96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
|
|
import time
|
||
|
|
|
||
|
|
from PySide6.QtCore import QTimer, Qt, QUrl
|
||
|
|
from PySide6.QtGui import QGuiApplication
|
||
|
|
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QProgressBar
|
||
|
|
|
||
|
|
|
||
|
|
class LoadingWindowController:
|
||
|
|
def __init__(self):
|
||
|
|
self.loading_window = None
|
||
|
|
self.loading_min_ms = 700
|
||
|
|
self.loading_started_ms = 0.0
|
||
|
|
|
||
|
|
def show(self):
|
||
|
|
self.loading_started_ms = time.time() * 1000
|
||
|
|
if self.loading_window is not None:
|
||
|
|
self.loading_window.show()
|
||
|
|
self.loading_window.raise_()
|
||
|
|
self.loading_window.activateWindow()
|
||
|
|
return self.loading_window
|
||
|
|
win = QWidget()
|
||
|
|
win.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
|
||
|
|
win.setAttribute(Qt.WA_DeleteOnClose, True)
|
||
|
|
win.resize(560, 220)
|
||
|
|
screen = QGuiApplication.primaryScreen()
|
||
|
|
if screen is not None:
|
||
|
|
geo = screen.availableGeometry()
|
||
|
|
win.move(geo.center().x() - win.width() // 2, geo.center().y() - win.height() // 2)
|
||
|
|
win.setStyleSheet("background:qlineargradient(x1:0,y1:0,x2:0,y2:1, stop:0 #f8fbff, stop:1 #eef4fb);border:1px solid #dbe7f5;border-radius:16px;")
|
||
|
|
lay = QVBoxLayout(win)
|
||
|
|
lay.setContentsMargins(30, 28, 30, 28)
|
||
|
|
lay.setSpacing(10)
|
||
|
|
|
||
|
|
title = QLabel("识流 AI 助手")
|
||
|
|
title.setStyleSheet("font-size:18px;font-weight:700;color:#0f172a;")
|
||
|
|
label = QLabel("正在启动服务与管理台…")
|
||
|
|
label.setStyleSheet("font-size:14px;color:#334155;")
|
||
|
|
hint = QLabel("首次启动会稍慢一点,请稍候")
|
||
|
|
hint.setStyleSheet("font-size:12px;color:#64748b;")
|
||
|
|
|
||
|
|
bar = QProgressBar()
|
||
|
|
bar.setRange(0, 0)
|
||
|
|
bar.setTextVisible(False)
|
||
|
|
bar.setFixedHeight(8)
|
||
|
|
bar.setStyleSheet("QProgressBar{background:#e5edf8;border:0;border-radius:4px;}QProgressBar::chunk{background:qlineargradient(x1:0,y1:0,x2:1,y2:0, stop:0 #22c1c3, stop:1 #3b82f6);border-radius:4px;}")
|
||
|
|
|
||
|
|
lay.addWidget(title)
|
||
|
|
lay.addWidget(label)
|
||
|
|
lay.addSpacing(4)
|
||
|
|
lay.addWidget(bar)
|
||
|
|
lay.addWidget(hint)
|
||
|
|
lay.addStretch(1)
|
||
|
|
|
||
|
|
self.loading_window = win
|
||
|
|
self.loading_window.show()
|
||
|
|
self.loading_window.raise_()
|
||
|
|
self.loading_window.activateWindow()
|
||
|
|
return self.loading_window
|
||
|
|
|
||
|
|
def close(self):
|
||
|
|
if self.loading_window is not None:
|
||
|
|
self.loading_window.close()
|
||
|
|
self.loading_window = None
|
||
|
|
|
||
|
|
def finish_with(self, callback):
|
||
|
|
elapsed = int(time.time() * 1000 - self.loading_started_ms) if self.loading_started_ms else self.loading_min_ms
|
||
|
|
remain = max(0, self.loading_min_ms - elapsed)
|
||
|
|
QTimer.singleShot(remain + 120, callback)
|
||
|
|
|
||
|
|
|
||
|
|
class WebViewShellController:
|
||
|
|
def __init__(self, web_view):
|
||
|
|
self.web_view = web_view
|
||
|
|
self.main_page_ready = False
|
||
|
|
self.expecting_admin_load = False
|
||
|
|
|
||
|
|
def load(self, entry_url):
|
||
|
|
if self.web_view is None:
|
||
|
|
return
|
||
|
|
self.main_page_ready = False
|
||
|
|
self.expecting_admin_load = True
|
||
|
|
self.web_view.setStyleSheet("background:#eef2f7;")
|
||
|
|
self.web_view.load(QUrl(entry_url))
|
||
|
|
|
||
|
|
def mark_loaded(self, ok):
|
||
|
|
if not self.expecting_admin_load or not ok:
|
||
|
|
return False
|
||
|
|
self.main_page_ready = True
|
||
|
|
return True
|
||
|
|
|
||
|
|
def can_finish(self):
|
||
|
|
return self.main_page_ready
|
||
|
|
|
||
|
|
def finish(self):
|
||
|
|
self.expecting_admin_load = False
|