【问题标题】:Tkinter focus_set and focus_force not working as expectedTkinter focus_set 和 focus_force 没有按预期工作
【发布时间】:2015-10-20 00:06:38
【问题描述】:

我正在尝试让 Entry 字段在新页面打开时获得焦点:

import tkinter as tk
from tkinter import *
from tkinter import ttk

class DIS(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.iconbitmap(self, default="")
        tk.Tk.wm_title(self, "program")
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        self.frames = {}

        for F in (startPage, contactQues):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")
            self.show_frame(startPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

class startPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        button2 = ttk.Button(self, text = "Here's a Button",
                    command=lambda: controller.show_frame(contactQues))
        button2.pack()

class contactQues(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)  
        self.controller = controller

        entry = Entry(self)
        entry.focus_force()
        entry.pack()

app = DIS()
app.mainloop()

如果我移动startPage 下的Entry 字段,则焦点设置正确——每当我将它移动到contactQues 时,它就会失去焦点。可能是顶级问题?

【问题讨论】:

  • 您的缩进有问题。代码不会像发布的那样运行。
  • @BryanOakley 我编辑了它,相信应该没问题

标签: python-3.x tkinter


【解决方案1】:

似乎tkraise() 搞乱了焦点。因此,您需要在将页面提升到视图后调用它。我会更新你的框架,在 tkraise 之后总是调用一些方法,如下所示:

import tkinter as tk
from tkinter import *
from tkinter import ttk

class DIS(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.iconbitmap(self, default="")
        tk.Tk.wm_title(self, "program")
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        self.frames = {}

        for F in (startPage, contactQues):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")
            self.show_frame(startPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()
        frame.postupdate()

class startPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        button2 = ttk.Button(self, text = "Here's a Button",
                    command=lambda: controller.show_frame(contactQues))
        button2.pack()

    def postupdate(self):
        pass

class contactQues(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)  
        self.controller = controller

        self.entry = Entry(self)
        self.entry.pack()

    def postupdate(self):
        self.entry.focus()

app = DIS()
app.mainloop()

如果你想避免在不需要 postupdate() 方法的地方使用它,你可以在尝试运行它之前检查它是否存在于类中。像这样:

def show_frame(self, cont):
    frame = self.frames[cont]
    frame.tkraise()
    try:
        frame.postupdate()
    except AttributeError:
        pass

【讨论】:

  • 是的,这解决了我的问题......虽然,诚然,我不完全理解如何。我必须阅读它是如何工作的。感谢您的帮助。
  • 嗯,这有点奇怪。但是我使用了与您以前相同的框架。您在 DIS 的 init 方法中所做的是绘制所有页面,基本上是在彼此的顶部,然后您使用 tkraise 使用 tkraise() 将您需要的页面拉到前面。由于某种原因,这似乎弄乱了焦点,因此您需要在将焦点拉到前面后设置焦点。这就是为什么我添加了一个额外的方法,该方法将在所有页面上调用。
  • 啊,我明白你的意思了。我是新手,所以我遇到的每一个小问题都能帮助我理解。谢谢。
  • 如果您是一般的编程新手,那么您可能应该暂时停止使用 GUI。这是一些令人困惑的东西。
【解决方案2】:

所以经过大量搜索后,我找到了解决此问题的方法。 只需将以下行添加到 show_frame 函数的末尾并删除 postupdate 调用:

return 'break'

它禁用事件传播到提升的帧下的其他帧。 anderswb 发布的解决方案对我不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 2013-07-07
    • 2012-12-05
    • 2017-05-22
    • 2019-07-28
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多