feat(事件悬停) 事件悬停功能重构,可自定义显示时间

This commit is contained in:
marcinlei@outlook.com 2025-08-24 01:00:04 +08:00
parent 63d36548aa
commit dcd3c54eb0

@ -4,7 +4,7 @@ import json
from PyQt5.QtWidgets import (QApplication, QWidget, QGraphicsView, QGraphicsScene, from PyQt5.QtWidgets import (QApplication, QWidget, QGraphicsView, QGraphicsScene,
QGraphicsTextItem, QToolTip, QVBoxLayout, QGraphicsTextItem, QToolTip, QVBoxLayout,
QTabWidget, QLabel) QTabWidget, QLabel)
from PyQt5.QtCore import Qt, QEvent from PyQt5.QtCore import Qt, QEvent, QTimer, QPoint
from PyQt5.QtGui import QPen, QBrush, QColor, QFont, QPainter from PyQt5.QtGui import QPen, QBrush, QColor, QFont, QPainter
class TimelineEvent: class TimelineEvent:
@ -15,6 +15,41 @@ class TimelineEvent:
self.title = title self.title = title
self.details = details # 详细信息字典 self.details = details # 详细信息字典
class CustomTooltip(QWidget):
"""自定义提示框,支持设置显示时长"""
def __init__(self, parent=None):
super().__init__(parent, Qt.ToolTip | Qt.FramelessWindowHint)
self.setWindowOpacity(0.95) # 半透明
# 设置样式
self.setStyleSheet("""
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
padding: 8px;
""")
self.layout = QVBoxLayout(self)
self.label = QLabel()
self.label.setFont(QFont("SimHei", 10))
self.label.setTextInteractionFlags(Qt.TextSelectableByMouse) # 允许选中文本
self.layout.addWidget(self.label)
# 定时器控制隐藏
self.hide_timer = QTimer(self)
self.hide_timer.setSingleShot(True)
self.hide_timer.timeout.connect(self.hide)
def setText(self, text):
self.label.setText(text)
self.adjustSize() # 自动调整大小以适应内容
def showAt(self, pos, duration=10000):
"""在指定位置显示duration为显示时长毫秒"""
self.move(pos)
self.show()
self.hide_timer.start(duration) # 10秒后自动隐藏
class TimelineGraphicsView(QGraphicsView): class TimelineGraphicsView(QGraphicsView):
"""时间线视图实现3个事件一组的高度调整和间隔时间戳显示""" """时间线视图实现3个事件一组的高度调整和间隔时间戳显示"""
def __init__(self, parent=None): def __init__(self, parent=None):
@ -54,6 +89,10 @@ class TimelineGraphicsView(QGraphicsView):
(0, 0, 150) # 组6 :浅蓝 (0, 0, 150) # 组6 :浅蓝
] ]
# 初始化自定义提示框
self.tooltip = CustomTooltip(self)
self.hovered_event = None # 当前悬停的事件
def wheelEvent(self, event): def wheelEvent(self, event):
"""鼠标滚轮缩放""" """鼠标滚轮缩放"""
delta = event.angleDelta().y() delta = event.angleDelta().y()
@ -69,23 +108,45 @@ class TimelineGraphicsView(QGraphicsView):
self.current_scale = new_scale self.current_scale = new_scale
def eventFilter(self, obj, event): def eventFilter(self, obj, event):
"""事件悬停提示""" """事件过滤器,处理鼠标移动和离开"""
if obj == self.viewport() and event.type() == QEvent.MouseMove: if obj == self.viewport():
scene_pos = self.mapToScene(event.pos()) if event.type() == QEvent.MouseMove:
self.handle_mouse_move(event)
for item, event_data in self.event_items: elif event.type() == QEvent.Leave:
if item.contains(item.mapFromScene(scene_pos)): # 鼠标离开视图时隐藏提示
details_text = f"<b>{event_data.title}</b><br>" self.tooltip.hide()
details_text += f"时间: {event_data.timestamp.strftime('%Y-%m-%d %H:%M:%S')}<br><br>" self.hovered_event = None
for key, value in event_data.details.items():
details_text += f"{key}: {value}<br>"
QToolTip.showText(event.globalPos(), details_text)
return True
QToolTip.hideText()
return super().eventFilter(obj, event) return super().eventFilter(obj, event)
def handle_mouse_move(self, event):
"""处理鼠标移动,显示/隐藏提示"""
scene_pos = self.mapToScene(event.pos())
current_hover = None
# 检查是否悬停在事件上
for item, event_data in self.event_items:
if item.contains(item.mapFromScene(scene_pos)):
current_hover = event_data
break
if current_hover:
if current_hover != self.hovered_event:
# 显示新的提示10秒后自动隐藏
self.hovered_event = current_hover
details_text = f"<b>{current_hover.title}</b><br>"
details_text += f"时间: {current_hover.timestamp.strftime('%Y-%m-%d %H:%M:%S')}<br><br>"
for key, value in current_hover.details.items():
details_text += f"{key}: {value}<br>"
# 在鼠标位置附近显示提示
global_pos = event.globalPos()
self.tooltip.setText(details_text)
self.tooltip.showAt(QPoint(global_pos.x() + 10, global_pos.y() + 10), 10000)
else:
# 没有悬停在事件上,隐藏提示
self.tooltip.hide()
self.hovered_event = None
def add_events(self, events): def add_events(self, events):
"""添加事件并按组布局""" """添加事件并按组布局"""