|
|
在标签页切换时激活当前标签页的滚轮管理器
1. 创建MouseWheelManager,使用全局事件分发
# ================= 改进的鼠标滚轮管理器 =================
class MouseWheelManager:
"""管理鼠标滚轮事件 - 全局分发版本"""
# 类变量,存储所有管理器
_all_managers = []
def __init__(self, canvas, tab_frame):
self.canvas = canvas
self.tab_frame = tab_frame
self.root_window = tab_frame.winfo_toplevel()
self.is_active = False
# 添加到管理器列表
MouseWheelManager._all_managers.append(self)
print(f"MouseWheelManager初始化: canvas={canvas}")
def bind_events(self):
"""绑定滚轮事件到全局窗口"""
def global_on_mousewheel(event):
# 查找当前激活的管理器
active_manager = None
for manager in MouseWheelManager._all_managers:
if manager.is_active:
active_manager = manager
break
if not active_manager:
return None
print(f"全局滚轮事件 -> 激活的管理器: {active_manager.canvas}")
# 检查鼠标是否在当前激活的标签页内
mouse_x = event.x_root
mouse_y = event.y_root
tab_x1 = active_manager.tab_frame.winfo_rootx()
tab_y1 = active_manager.tab_frame.winfo_rooty()
tab_x2 = tab_x1 + active_manager.tab_frame.winfo_width()
tab_y2 = tab_y1 + active_manager.tab_frame.winfo_height()
# 如果鼠标在当前激活的标签页内,则滚动
if tab_x1 <= mouse_x <= tab_x2 and tab_y1 <= mouse_y <= tab_y2:
if hasattr(event, 'delta') and event.delta:
active_manager.canvas.yview_scroll(int(-event.delta / 120), "units")
print(f"滚动: {int(-event.delta / 120)}")
elif event.num == 4:
active_manager.canvas.yview_scroll(-1, "units")
print("向上滚动")
elif event.num == 5:
active_manager.canvas.yview_scroll(1, "units")
print("向下滚动")
return "break"
return None
# 绑定到根窗口(只绑定一次)
if not hasattr(self.root_window, '_mousewheel_bound'):
self.root_window.bind_all("<MouseWheel>", global_on_mousewheel)
self.root_window.bind_all("<Button-4>", global_on_mousewheel)
self.root_window.bind_all("<Button-5>", global_on_mousewheel)
self.root_window._mousewheel_bound = True
print(f"全局滚轮绑定到根窗口: {self.root_window}")
def activate(self):
"""激活当前管理器的滚轮处理"""
# 停用所有其他管理器
for manager in MouseWheelManager._all_managers:
manager.deactivate()
# 激活当前管理器
self.is_active = True
print(f"激活滚轮管理器: {self.canvas}")
def deactivate(self):
"""停用当前管理器的滚轮处理"""
self.is_active = False
def cleanup(self):
"""清理绑定"""
self.deactivate()
if self in MouseWheelManager._all_managers:
MouseWheelManager._all_managers.remove(self)
print(f"MouseWheelManager清理: {self.canvas}")
2. 在ReportView中创建并激活管理器
def ReportView(root, current_data=None, file_path=None):
# ... 现有代码 ...
# ================= 创建滚轮管理器 =================
wheel_manager = MouseWheelManager(canvas, main_frame)
wheel_manager.bind_events()
wheel_manager.activate() # 立即激活
# ================= 滚动区域修正(关键) =================
root.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"))
# 添加清理函数
def cleanup():
print("解除鼠标滚轮绑定")
try:
wheel_manager.cleanup()
except Exception as e:
print(f"清理错误: {e}")
# 当ReportView被销毁时清理绑定
main_frame.cleanup = cleanup
# 返回滚轮管理器以便外部管理
return wheel_manager
3. 在main2.py中管理标签页激活
# 在main2.py的on_tab_changed方法中激活当前标签页的滚轮管理器
def on_tab_changed(self, event=None):
current_tab_id = self.tab_control.select()
if not current_tab_id:
return
tab_frame = self.tab_control.nametowidget(current_tab_id)
tab_text = self.tab_control.tab(current_tab_id, "text")
if tab_text == "欢迎":
# ✅ 欢迎页:清空导航状态
if hasattr(self, "navbar"):
self.navbar.clear()
self.current_file = None
self.update_status("就绪 - 未打开任何文件")
return
# 普通文件页
self.current_file = tab_text
self.update_status(f"当前文件: {tab_text}")
if hasattr(self, "navbar"):
self.navbar.sync_with_tab(tab_frame)
# 激活当前标签页的滚轮管理器
if hasattr(tab_frame, '_wheel_manager'):
tab_frame._wheel_manager.activate()
# 在create_file_tab方法中存储管理器
def create_file_tab(self, display_name: str, data: Dict[str, Any]) -> None:
"""为文件创建标签页"""
# 创建标签页框架
tab_frame = ttk.Frame(self.tab_control)
# 添加标签页
self.tab_control.add(tab_frame, text=display_name)
# 存储标签页引用
self.file_tabs[display_name] = tab_frame
# 设置当前文件
self.current_file = display_name
# 切换到新标签页
self.tab_control.select(tab_frame)
# 显示基本信息页面
self.show_page("基本信息")
# 设置默认页面状态
tab_frame._current_page_name = "基本信息"
# 修改show_page方法以存储滚轮管理器
def show_page(self, page_name: str) -> None:
if not self.current_file:
messagebox.showinfo("提示", "请先打开一个脑波数据文件")
return
try:
current_tab_id = self.tab_control.select()
tab_frame = self.tab_control.nametowidget(current_tab_id)
current_page = getattr(tab_frame, '_current_page', None)
if current_page == page_name:
return
for widget in tab_frame.winfo_children():
widget.destroy()
tab_frame._current_page = page_name
tab_frame._current_page_name = page_name
current_data = self.open_files.get(self.current_file, {})
parsed_data = "".join(current_data['lines'])
# 页面选择逻辑
page_map = {
"基本信息": ReportView
}
page_cls = page_map.get(page_name, None)
if page_cls:
# 创建页面并获取滚轮管理器
wheel_manager = page_cls(tab_frame, current_data=parsed_data, file_path=current_data['metadata']['file_path'])
# 存储滚轮管理器
tab_frame._wheel_manager = wheel_manager
# 激活当前管理器
wheel_manager.activate()
else:
placeholder = ttk.Label(tab_frame, text=f"{page_name}页面开发中...", font=("Arial", 16))
placeholder.pack(expand=True)
# ✅ 确保导航同步
if hasattr(self, "navbar"):
self.navbar.select(page_name)
except Exception as e:
messagebox.showerror("错误", f"显示页面失败:\n{str(e)}") |
|