【问题标题】:Python tkinter bindtag Event handling - how to update which tab is currently selectedPython tkinter bindtag 事件处理 - 如何更新当前选择的选项卡
【发布时间】:2018-01-04 21:47:28
【问题描述】:

我是 Python 新手,即将使用 tkinter 构建一个 GUI。 GUI 由一个笔记本组成,我正在尝试为用户在不同选项卡上单击鼠标时创建一个事件处理程序。但是,当我单击一个选项卡时,处理函数“工作”,但似乎在调用该函数之前所选选项卡没有“更新”。

作为旁注:到目前为止,我主要使用了 'Tkinter 8.5 reference: a GUI for 蟒蛇(船夫)'。请看下面的代码。感谢任何建议!

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()

【问题讨论】:

  • note.bind('&lt;&lt;NotebookTabChanged&gt;&gt;',personalData)

标签: python tkinter bind


【解决方案1】:

发生这种情况的原因是事件的处理顺序。小部件上的自定义绑定在内置绑定之前处理,这意味着您在&lt;1&gt; 上的绑定将在选项卡实际更改之前触发。有关更多信息,请研究“绑定标签”(或有时称为“绑定标签”或“绑定标签”)。

更好的解决方案是绑定虚拟事件&lt;&lt;NotebookTabChanged&gt;&gt;,该事件会在选项卡更改后笔记本会生成。

例子:

note.bind("<<NotebookTabChanged>>", personalData)

绑定到虚拟事件而不是鼠标单击的另一个好处是,即使通过鼠标单击之外的其他机制更改选项卡,该事件也会触发。例如,如果一个选项卡具有键盘焦点,您可以使用键盘上的箭头键选择下一个或上一个选项卡。

【讨论】:

    【解决方案2】:

    您遇到这种情况是因为events of bind are handled before events of bindtags,换句话说,您实际上没有在处理回调函数为"&lt;1&gt;" 事件personalData 之前更改选项卡。 p>


    一种解决方法是轮换处理事件的顺序。在note.bind(...)之后添加:

    note.bindtags((note.bindtags()[1:] + note.bindtags()[:1]))
    

    这会将绑定的回调作为序列中的最后一个,并将其余部分移到队列中。


    另一种方法是将实际事件 ("&lt;1&gt;") 替换为更合适的事件,例如 Novel's suggestion

    【讨论】:

    • 不像其他解决方案那样喜欢这种解决方法,但我喜欢这种解释
    【解决方案3】:

    注意,当你点击另一个标签时,当前标签仍然是前一个标签;如果您将绑定更改为

    note.bind('<ButtonRelease-1>',personalData)
    

    它会正常工作,就像现在一样,当释放鼠标按钮时,当前选项卡就是已经选择的选项卡。

    【讨论】:

    • 此解决方案的缺点是,如果用户使用键盘切换选项卡(当笔记本选项卡具有键盘焦点时,您可以使用左右箭头执行此操作),它将不起作用。
    • 当然,我同意你对虚拟活动&lt;&lt;NotebookTabChanged&gt;&gt;的首选使用。
    • 谢谢!对键盘焦点也做出反应的可能性是有意义的。
    • 谢谢,现在它工作正常!对键盘焦点也做出反应的可能性是有道理的。实际上,在问这个问题之前,我写了 note.bind('> (第 128 页的 GUI for tkinter) 没有意识到 '-' 是由于教程中的换行引起的(我很愚蠢..)但是,在运行此代码时,我没有收到任何令我惊讶的错误消息(IDLE Shell)。
    • @user2423970 从技术上讲,'&lt;&lt;NotebookT-abChanged&gt;&gt;' 是一个有效的虚拟事件标识符。 Tkinter 无法知道您是否在代码的其他地方创建(或计划创建)类似的事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多