Python tkinter.Text中的小部件打断鼠标滚轮

Python tkinter.Text中的小部件打断鼠标滚轮,python,tkinter,tk,Python,Tkinter,Tk,tkinter.Text小部件允许其他小部件(如按钮)与纯文本一起插入 tkinter.Text小部件通过滚动内容响应鼠标滚轮。但是,如果光标恰好位于子小部件上,该小部件将获得鼠标滚轮事件,并且文本不会滚动。相反,我希望文本获取此鼠标滚轮事件 解决这个问题的好方法是什么 这是tkinter.Text内部小部件的默认行为,但下面是一些代码来演示这个问题 import tkinter as tk root = tk.Tk() s = '\nTesting mouse wheel scroll wi

tkinter.Text
小部件允许其他小部件(如按钮)与纯文本一起插入

tkinter.Text
小部件通过滚动内容响应鼠标滚轮。但是,如果光标恰好位于子小部件上,该小部件将获得鼠标滚轮事件,并且
文本不会滚动。相反,我希望
文本
获取此鼠标滚轮事件

解决这个问题的好方法是什么


这是
tkinter.Text
内部小部件的默认行为,但下面是一些代码来演示这个问题

import tkinter as tk
root = tk.Tk()
s = '\nTesting mouse wheel scroll with widgets inside tkinter.Text.\n'
txt = tk.Text(root, width=40, height=6)
for i in range(5):
    b = tk.Button(txt, text='I Break Scroll')
    txt.window_create(tk.END, window=b, padx=5, pady=5)
    txt.insert(tk.END, s)
txt.pack()
root.mainloop()

鼠标滚轮事件被发送到光标下的小部件。这使得用鼠标控制多个可滚动的小部件成为可能。在tkinter的旧版本中,它使用焦点滚动窗口

对于不可滚动的小部件,没有默认行为。当您在按钮或标签上移动鼠标滚轮时,滚动停止,因为事件指向按钮或标签,而不是文本

您似乎不希望出现这种行为,因此需要为不可滚动的小部件提供自己的鼠标滚轮绑定。如果将这些绑定应用于小部件类而不是单个小部件,那么就不必绑定到每个小部件。不过,如果愿意,您可以绑定到各个小部件

下面的示例为
按钮
标签
小部件类添加绑定,以将事件传递给其父类

import tkinter as tk

root = tk.Tk()
text = tk.Text(root, wrap="word")
vsb = tk.Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=vsb.set)

vsb.pack(side="right", fill="y")
text.pack(side="left", fill="both", expand=True)

for i in range(200):
    text.insert("end", f"Item #{i}")
    if i%5 == 0:
        b = tk.Button(text, text=f"A button")
        text.window_create("end", window=b)
    elif i%3 == 0:
        l = tk.Button(text, text=f"A label")
        text.window_create("end", window=l)
    text.insert("end", "\n")

def scroll_parent(event):
    parent = root.nametowidget(event.widget.winfo_parent())
    parent.event_generate("<MouseWheel>", delta=event.delta, when="now")

root.bind_class("Button", "<MouseWheel>", scroll_parent)
root.bind_class("Label", "<MouseWheel>", scroll_parent)

root.mainloop()
将tkinter作为tk导入
root=tk.tk()
text=tk.text(root,wrap=“word”)
vsb=tk.Scrollbar(根,命令=text.yview)
text.configure(yscrollcommand=vsb.set)
vsb.pack(side=“right”,fill=“y”)
text.pack(side=“left”,fill=“both”,expand=True)
对于范围(200)内的i:
正文.插入(“结束”,f“项目{i}”)
如果i%5==0:
b=tk.按钮(文本,文本=f“A按钮”)
text.window\u创建(“结束”,window=b)
elif i%3==0:
l=tk.按钮(文本,文本=f“A标签”)
text.window\u创建(“结束”,window=l)
文本。插入(“结束”、“\n”)
def scroll_父级(事件):
parent=root.nametWidget(event.widget.winfo\u parent())
parent.event_generate(“,delta=event.delta,when=“now”)
root.bind\u类(“按钮”,“滚动\u父级”)
root.bind\u类(“标签”,“滚动\u父级”)
root.mainloop()

注意:如果您使用的是基于X11的系统,则需要调整此代码以绑定到
,而不是

鼠标滚轮事件发送到光标下的小部件。这使得用鼠标控制多个可滚动的小部件成为可能。在tkinter的旧版本中,它使用焦点滚动窗口

对于不可滚动的小部件,没有默认行为。当您在按钮或标签上移动鼠标滚轮时,滚动停止,因为事件指向按钮或标签,而不是文本

您似乎不希望出现这种行为,因此需要为不可滚动的小部件提供自己的鼠标滚轮绑定。如果将这些绑定应用于小部件类而不是单个小部件,那么就不必绑定到每个小部件。不过,如果愿意,您可以绑定到各个小部件

下面的示例为
按钮
标签
小部件类添加绑定,以将事件传递给其父类

import tkinter as tk

root = tk.Tk()
text = tk.Text(root, wrap="word")
vsb = tk.Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=vsb.set)

vsb.pack(side="right", fill="y")
text.pack(side="left", fill="both", expand=True)

for i in range(200):
    text.insert("end", f"Item #{i}")
    if i%5 == 0:
        b = tk.Button(text, text=f"A button")
        text.window_create("end", window=b)
    elif i%3 == 0:
        l = tk.Button(text, text=f"A label")
        text.window_create("end", window=l)
    text.insert("end", "\n")

def scroll_parent(event):
    parent = root.nametowidget(event.widget.winfo_parent())
    parent.event_generate("<MouseWheel>", delta=event.delta, when="now")

root.bind_class("Button", "<MouseWheel>", scroll_parent)
root.bind_class("Label", "<MouseWheel>", scroll_parent)

root.mainloop()
将tkinter作为tk导入
root=tk.tk()
text=tk.text(root,wrap=“word”)
vsb=tk.Scrollbar(根,命令=text.yview)
text.configure(yscrollcommand=vsb.set)
vsb.pack(side=“right”,fill=“y”)
text.pack(side=“left”,fill=“both”,expand=True)
对于范围(200)内的i:
正文.插入(“结束”,f“项目{i}”)
如果i%5==0:
b=tk.按钮(文本,文本=f“A按钮”)
text.window\u创建(“结束”,window=b)
elif i%3==0:
l=tk.按钮(文本,文本=f“A标签”)
text.window\u创建(“结束”,window=l)
文本。插入(“结束”、“\n”)
def scroll_父级(事件):
parent=root.nametWidget(event.widget.winfo\u parent())
parent.event_generate(“,delta=event.delta,when=“now”)
root.bind\u类(“按钮”,“滚动\u父级”)
root.bind\u类(“标签”,“滚动\u父级”)
root.mainloop()

注意:如果您使用的是基于X11的系统,则需要调整此代码以绑定到
,而不是

投票关闭:您没有提供任何代码,因此很难告诉您如何更改代码以使其正常工作。基本上,您将绑定文本小部件内的每个对象以响应鼠标滚轮操作,但将事件传递给文本小部件。也许您可以提供一个简单的例子,在文本小部件中包含一个对象。@scotty3785:有一种比绑定到文本小部件中的每个小部件更好的方法。@BryanOakley用您的智慧启发我们:P@BryanOakley我当然希望有比绑定
文本
中的所有内容更好的方法。投票结束:您没有提供任何代码很难告诉您如何更改代码以使其工作。基本上,您将绑定文本小部件内的每个对象以响应鼠标滚轮操作,但将事件传递给文本小部件。也许您可以提供一个简单的例子,在文本小部件中包含一个对象。@scotty3785:有一种比绑定到文本小部件中的每个小部件更好的方法。@BryanOakley用您的智慧启发我们:P@BryanOakley我当然希望有一种比在
文本中绑定所有内容更好的方法。谢谢。因此,没有办法阻止
文本
中不可滚动的小部件首先获得
事件?@mcu:AFAIK没有办法阻止它,就像没有办法阻止按钮接收鼠标点击,或者阻止输入小部件接收键盘事件一样。谢谢。因此,没有办法阻止
文本
中不可滚动的小部件首先获得
事件?@mcu:AFAIK没有办法阻止,很多