我是Python新手,即将使用tkinter构建GUI。 GUI由一个Notebook组成,我正在尝试为用户在不同选项卡上单击鼠标时创建一个事件处理程序。但是,当我点击一个标签时,处理程序功能可以正常运行'但似乎所选标签没有更新'在调用函数之前。
作为旁注:到目前为止,我主要使用了' Tkinter 8.5参考:用于GUI的GUI Python(希普曼)'。请参阅下面的代码。感谢任何建议!
from tkinter import *
import tkinter.ttk as ttk
root = Tk()
note = ttk.Notebook(root)
tab1 = Frame(note,width = 10)
tab2 = Frame(note,width = 10)
tab3 = Frame(note,width = 10)
note.add(tab1, text = "Tab One")
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.grid()
def personalData(event):
if event.widget.index("current") == 0:
print("One!")
else:
print("Not One!")
note.bind('<1>',personalData)
root.mainloop()
答案 0 :(得分:2)
发生这种情况的原因是由于处理事件的顺序。小部件上的自定义绑定在内置绑定之前处理,这意味着<1>
上的绑定将在选项卡实际更改之前触发。有关更多信息,请研究“绑定标记”(或有时称为“绑定标记”或“绑定标记”)。
更好的解决方案是绑定虚拟事件<<NotebookTabChanged>>
,笔记本将在更改选项卡后生成。
示例:
note.bind("<<NotebookTabChanged>>", personalData)
绑定到虚拟事件而不是鼠标单击的另一个好处是,即使通过鼠标单击之外的其他一些机制更改了选项卡,事件也会触发。例如,如果选项卡具有键盘焦点,则可以使用键盘上的箭头键选择下一个或上一个选项卡。
答案 1 :(得分:1)
您遇到此问题是因为events of bind are handled before events of bindtags,换句话说,您实际上不在回调函数之前将标签更改为"<1>"
事件,{{1}处理完毕。
一种解决方法是旋转正在处理事件的序列的顺序。在personalData
之后添加:
note.bind(...)
这会将bind的回调作为序列中的最后一个,并将其余部分转移到队列中。
另一种方法是将实际事件(note.bindtags((note.bindtags()[1:] + note.bindtags()[:1]))
)替换为更合适的事件,例如Novel's suggestion。
答案 2 :(得分:0)
请注意,当您单击另一个选项卡时,当前选项卡仍然是上一个选项卡;如果您将绑定更改为
note.bind('<ButtonRelease-1>',personalData)
它将正常工作,就像现在一样,当释放鼠标按钮时,当前选项卡是已经选中的选项卡。