由前端事件冒泡机制引发的 Tkinter 事件机制测试与辨析
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>控制台输出的事件冒泡演示</title> <style> /* 基础样式 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", sans-serif; } body { padding: 50px; background-color: #f5f7fa; } .container { max-width: 500px; margin: 0 auto; } /* 层级元素样式 */ .level { padding: 25px; margin: 15px; border-radius: 6px; cursor: pointer; } .parent { background-color: #e6f7ff; border: 2px solid #1890ff; } .child { background-color: #f0fff4; border: 2px solid #52c41a; } .grandchild { background-color: #fffbe6; border: 2px solid #faad14; text-align: center; } /* 按钮样式 */ button { margin: 20px 15px; padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background-color: #096dd9; } </style> </head> <body> <div class="container"> <!-- 父元素 --> <div class="level parent" id="parent"> <h3>父元素(点击我)</h3> <p>绑定事件:控制台输出 "1"</p> <!-- 子元素 --> <div class="level child" id="child"> <h3>子元素(点击我)</h3> <p>绑定事件:控制台输出 "2"</p> <!-- 孙元素 --> <div class="level grandchild" id="grandchild"> <h3>孙元素(点击我)</h3> <p>绑定事件:控制台输出 "3"</p> </div> </div> </div> <!-- 控制按钮 --> <button id="toggleBtn">切换:当前【不阻止】冒泡</button> </div> <script> // 获取元素 const parent = document.getElementById('parent'); const child = document.getElementById('child'); const grandchild = document.getElementById('grandchild'); const toggleBtn = document.getElementById('toggleBtn'); // 状态变量 let preventBubble = false; // 事件处理函数 - 直接输出到控制台 function parentHandler() { console.log('%c父元素触发 → 输出 "1"', 'color: #1890ff'); } function childHandler() { console.log('%c子元素触发 → 输出 "2"', 'color: #52c41a'); } function grandchildHandler(event) { console.log('%c孙元素触发 → 输出 "3"', 'color: #faad14'); // 根据状态决定是否阻止冒泡 if (preventBubble) { event.stopPropagation(); console.log('%c已阻止事件冒泡', 'color: #ff4d4f'); } } // 绑定事件 parent.addEventListener('click', parentHandler); child.addEventListener('click', childHandler); grandchild.addEventListener('click', grandchildHandler); // 切换按钮事件 toggleBtn.addEventListener('click', () => { preventBubble = !preventBubble; toggleBtn.textContent = `切换:当前【${preventBubble ? '阻止' : '不阻止'}】冒泡`; console.log(`%c状态切换:${preventBubble ? '已开启' : '已关闭'}事件冒泡阻止`, 'color: #722ed1'); }); // 初始化提示 console.log('🎉 事件绑定完成,请打开控制台并点击元素测试'); console.log('提示:点击孙元素查看完整冒泡过程,点击按钮可切换是否阻止冒泡'); </script> </body> </html>
import tkinter as tk from tkinter import ttk # 事件处理函数:打印当前触发的控件层级 def parent_func(event): print("父控件触发 → 打印1") def child_func(event): print("子控件触发 → 打印2") def grandchild_func(event): print("孙控件触发 → 打印3") # 创建主窗口 root = tk.Tk() root.title("带文字标识的Tkinter事件测试") root.geometry("500x400") # 配置样式,让控件更易区分 style = ttk.Style() style.configure("Parent.TFrame", background="#e6f7ff", borderwidth=2, relief="solid") style.configure("Child.TFrame", background="#f0fff4", borderwidth=2, relief="solid") style.configure("Grandchild.TFrame", background="#fffbe6", borderwidth=2, relief="solid") style.configure("TLabel", font=("Microsoft YaHei", 10)) # ---------------------- 父控件 ---------------------- parent = ttk.Frame(root, style="Parent.TFrame", padding=20) parent.pack(fill=tk.BOTH, expand=True, padx=30, pady=15) parent.bind("<Button-1>", parent_func) # 父控件样式 ttk.Label( parent, text="父控件", background="#e6f7ff", font=("Microsoft YaHei", 12, "bold") ).pack(anchor="w") ttk.Label( parent, text="点击区域:触发时打印 1", background="#e6f7ff" ).pack(anchor="w", pady=(0, 10)) # ---------------------- 子控件 ---------------------- child = ttk.Frame(parent, style="Child.TFrame", padding=20) child.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) child.bind("<Button-1>", child_func) # 子控件样式 ttk.Label( child, text="子控件", background="#f0fff4", font=("Microsoft YaHei", 12, "bold") ).pack(anchor="w") ttk.Label( child, text="点击区域:触发时打印 2", background="#f0fff4" ).pack(anchor="w", pady=(0, 10)) # ---------------------- 孙控件 ---------------------- grandchild = ttk.Frame(child, style="Grandchild.TFrame", padding=20) grandchild.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) grandchild.bind("<Button-1>", grandchild_func) # 孙控件样式 ttk.Label( grandchild, text="孙控件", background="#fffbe6", font=("Microsoft YaHei", 12, "bold") ).pack(anchor="w") ttk.Label( grandchild, text="点击区域:触发时打印 3", background="#fffbe6" ).pack(anchor="w", pady=(0, 10)) ttk.Label( grandchild, text="👉 点击此处测试事件触发", background="#fffbe6", foreground="#faad14" ).pack(anchor="w") # 启动主循环 root.mainloop()
总结:

浙公网安备 33010602011771号