Tkinter中Notebook标签左键点击的事件处理器

1 投票
1 回答
4243 浏览
提问于 2025-04-18 09:49

在Tkinter中,我想要实现一个功能,就是当我点击已经打开或选中的Notebook对象的标签时,不让它获得焦点(或者让焦点回到窗口中的文本框)。

我该怎么做呢?

如果有一个事件处理程序可以处理标签的点击,那就太好了。

另外,如果有办法让控件可以接收事件,但不获得焦点,那就更棒了。

我已经知道有一个虚拟事件<<NotebookTabChanged>>。不过,我说的是当你点击一个已经选中的标签时。也就是说,标签并没有改变。我尝试将<Button-1>事件绑定到Notebook控件上,但没有任何效果。

由于制作Notebook并不是每个使用Tkinter的人都知道的知识,这里有一个如何制作一个最简单的带标签的Notebook的例子。不过,我不知道为什么最后一个标签中的文本被截断了(但在我的完整代码中并没有这个问题):

from tkinter import *;
from tkinter.ttk import *; #Notebook comes from this

class Editor:
    def __init__(self):
        self.tk=Tk();
        self.tabs=0;
        self.frame=Frame(self.tk);
        self.nb=Notebook(self.frame);
        self.frame.pack();        
        for x in range(5):
            self.add_tab();
        self.nb.pack();
        self.tk.mainloop();
    def add_tab(self):
        newTabFrame=Frame(self.nb);
        text=Text(newTabFrame); #Just a sample Text widget to go in each tab
        text.pack();
        if self.tabs==0:
            self.nb.add(newTabFrame, text=str(self.tabs), compound=TOP);
        else:
            self.nb.add(newTabFrame, text=str(self.tabs));
        self.tabs+=1;

if __name__ == '__main__':
    e=Editor();
    try:
        e.tk.destroy();
    except:
        pass;

1 个回答

0

好吧,显然我之前做错了什么,因为当我在我问题中提到的示例代码上测试我以为已经测试过的更大代码时,它实际上是有效的。然后,我发现这个方法在我的大代码上也能用。真奇怪。我想我可能是用错了bind_all,而不是bind(虽然我以为我都试过了),因为bind_all确实不管用。编辑:实际上,我尝试在没有return "break"的情况下使用它,虽然这部分有效,但在你点击新标签后再次直接点击时就不行了。而且,我在这里用return "break"设置焦点并不能解决问题(虽然它回答了我的问题),因为它会在切换标签之前把焦点设置到当前标签上。我一定会想出解决办法的。编辑:把Button-1改成ButtonRelease-1(或者类似的东西)解决了这个问题。用相同的处理程序绑定Motion也有潜力,但如果你有弹出的Toplevel窗口,当你把鼠标指针移到标签上时,它会把焦点从这些窗口移开。

这是有效的代码:

from tkinter import *;
from tkinter.ttk import *; #Notebook comes from this
from tkinter.messagebox import *;

class Editor:
    def __init__(self):
        self.tk=Tk();
        self.tabs=0;
        self.frame=Frame(self.tk);
        self.nb=Notebook(self.frame);
        self.nb.bind("<ButtonRelease-1>", self.test);
        self.frame.pack();        
        for x in range(5):
            self.add_tab();
        self.nb.pack();
        self.tk.mainloop();
    def add_tab(self):
        newTabFrame=Frame(self.nb);
        text=Text(newTabFrame);
        text.pack();
        if self.tabs==0:
            self.nb.add(newTabFrame, text=str(self.tabs), compound=TOP);
        else:
            self.nb.add(newTabFrame, text=str(self.tabs));
        self.tabs+=1;
    def test(self, event=None):
        showinfo("Success", "It works!");
        #Imagine the code for selecting the text widget is here.
        return "break";

if __name__ == '__main__':
    e=Editor();
    try:
        e.tk.destroy();
    except:
        pass;

撰写回答