Files
dtm-py-all/UI/ui_utils/splash_window.py

221 lines
6.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
启动和关闭提示窗口
使用 tkinter 实现轻量级的提示界面
"""
import tkinter as tk
from tkinter import ttk
import threading
import time
class SplashWindow:
"""启动提示窗口"""
def __init__(self, title="正在启动", message="系统正在加载,请稍候..."):
self.window = None
self.title = title
self.message = message
self._closed = False
def show(self):
"""显示启动窗口(在单独线程中)"""
self._window_ready = threading.Event()
def _create_window():
self.window = tk.Tk()
self.window.title(self.title)
# 窗口大小和位置
width = 400
height = 150
screen_width = self.window.winfo_screenwidth()
screen_height = self.window.winfo_screenheight()
x = (screen_width - width) // 2
y = (screen_height - height) // 2
self.window.geometry(f"{width}x{height}+{x}+{y}")
# 无边框、置顶
self.window.overrideredirect(True)
self.window.attributes('-topmost', True)
# 背景色
self.window.configure(bg='#f0f0f0')
# 创建主框架
main_frame = tk.Frame(self.window, bg='#f0f0f0', padx=20, pady=20)
main_frame.pack(fill=tk.BOTH, expand=True)
# 标题
title_label = tk.Label(
main_frame,
text="跌落试验管理系统",
font=('Microsoft YaHei', 16, 'bold'),
bg='#f0f0f0',
fg='#333333'
)
title_label.pack(pady=(0, 10))
# 提示信息
message_label = tk.Label(
main_frame,
text=self.message,
font=('Microsoft YaHei', 11),
bg='#f0f0f0',
fg='#666666'
)
message_label.pack(pady=(0, 15))
# 进度条
self.progress = ttk.Progressbar(
main_frame,
mode='indeterminate',
length=350
)
self.progress.pack()
self.progress.start(10) # 开始动画
# 边框
border_frame = tk.Frame(self.window, bg='#3A84FF', bd=0)
border_frame.place(x=0, y=0, relwidth=1, height=3)
# 强制刷新显示
self.window.update_idletasks()
self.window.update()
# 标记窗口已准备好
self._window_ready.set()
# 运行主循环
self.window.mainloop()
# 在单独线程中创建窗口
self.thread = threading.Thread(target=_create_window, daemon=True)
self.thread.start()
# 等待窗口创建完成最多等待2秒
self._window_ready.wait(timeout=2.0)
def close(self):
"""关闭启动窗口"""
if self.window and not self._closed:
try:
self._closed = True
# 在 tkinter 线程中关闭窗口
if self.window:
self.window.after(0, self._safe_close)
# 等待线程结束最多0.5秒)
if self.thread and self.thread.is_alive():
self.thread.join(timeout=0.5)
except Exception as e:
print(f"关闭启动窗口时出错: {e}")
def _safe_close(self):
"""安全关闭窗口(在 tkinter 线程中执行)"""
try:
if self.window:
self.window.quit()
self.window.destroy()
except Exception as e:
print(f"关闭窗口时出错: {e}")
class ClosingWindow:
"""关闭提示窗口"""
def __init__(self, title="正在关闭", message="系统正在关闭,请稍候..."):
self.window = None
self.title = title
self.message = message
self._closed = False
def show(self):
"""显示关闭窗口(在主线程中)"""
self.window = tk.Tk()
self.window.title(self.title)
# 窗口大小和位置
width = 400
height = 150
screen_width = self.window.winfo_screenwidth()
screen_height = self.window.winfo_screenheight()
x = (screen_width - width) // 2
y = (screen_height - height) // 2
self.window.geometry(f"{width}x{height}+{x}+{y}")
# 无边框、置顶
self.window.overrideredirect(True)
self.window.attributes('-topmost', True)
# 背景色
self.window.configure(bg='#f0f0f0')
# 创建主框架
main_frame = tk.Frame(self.window, bg='#f0f0f0', padx=20, pady=20)
main_frame.pack(fill=tk.BOTH, expand=True)
# 标题
title_label = tk.Label(
main_frame,
text="跌落试验管理系统",
font=('Microsoft YaHei', 16, 'bold'),
bg='#f0f0f0',
fg='#333333'
)
title_label.pack(pady=(0, 10))
# 提示信息
message_label = tk.Label(
main_frame,
text=self.message,
font=('Microsoft YaHei', 11),
bg='#f0f0f0',
fg='#666666'
)
message_label.pack(pady=(0, 15))
# 进度条
"""
self.progress = ttk.Progressbar(
main_frame,
mode='indeterminate',
length=350
)
self.progress.pack()
self.progress.start(10) # 开始动画
"""
# 边框
border_frame = tk.Frame(self.window, bg='#ff6b6b', bd=0)
border_frame.place(x=0, y=0, relwidth=1, height=3)
# 刷新窗口
self.window.update()
def close(self):
"""关闭窗口"""
if self.window and not self._closed:
try:
self._closed = True
self.window.quit()
self.window.destroy()
except Exception as e:
print(f"关闭提示窗口时出错: {e}")
def update_message(self, message):
"""更新提示信息"""
if self.window:
try:
# 查找message_label并更新
for widget in self.window.winfo_children():
if isinstance(widget, tk.Frame):
for child in widget.winfo_children():
if isinstance(child, tk.Label) and child.cget('font')[1] == 11:
child.config(text=message)
break
self.window.update()
except Exception as e:
print(f"更新提示信息时出错: {e}")