Tkinter focus_set 和 focus_force 未按预期工作 [英] Tkinter focus_set and focus_force not working as expected

查看:37
本文介绍了Tkinter focus_set 和 focus_force 未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to have the Entry field to have focus when a new page opens up:

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 时,它就会丢失重点.可能是顶级问题?

If I move the Entry field under startPage, the focus is set correctly -- whenever I move it to contactQues, it loses the focus. Possibly a Toplevel issue?

推荐答案

似乎 tkraise() 把焦点弄乱了.因此,您需要在将页面提升到视图中后调用它.我会更新您的框架,以便在 tkraise 之后始终调用某些方法,如下所示:

It seems like tkraise() messes up the focus. So you need to invoke it after you've raised the page into view. I'd update you framework to always call some method after tkraise like so:

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() 方法,您可以在尝试运行它之前检查它是否存在于类中.像这样:

If you want to avoid having the postupdate() method where it's not needed, you could check to see if it exists in the class before trying to run it. Like so:

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

这篇关于Tkinter focus_set 和 focus_force 未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆