【问题标题】:Tkinter Bind Enter to Focus next EntryTkinter 将 Enter 绑定到焦点下一个条目
【发布时间】:2018-03-08 07:09:55
【问题描述】:

我正在尝试创建一个函数,将 enter 绑定到“插入”框架中的下一个输入字段。除了在最后一个输入字段的情况下,它将返回所有输入的文本字段。我尝试使用迭代器来获取下一个输入字段无济于事。我是 Python 和 Tkinter 的新手。我的主要问题围绕着“getinsert”函数,我怎样才能专注于下一个输入字段?有某种方式来获取当前焦点并为其添加 1?另外,我如何检查它是否在最后一个字段上,以便我可以调用“getinsert”函数?

任何帮助将不胜感激

import tkinter as tk
from tkinter import messagebox

master = tk.Tk()

insertnames = ["Title", "Location", "Tags", "Section", "Blah"]
insertentries = {}
insertlabels = {}
main = tk.Frame(master)
insert = tk.Frame(master)
currentnames = iter(insertnames[0])

def mainmenu():
    main.pack()
    insertbutton.pack(fill = 'x')

def insertcall():
    main.forget()
    insert.pack()
    insertform()
    insertentries["Title"].bind('<Return>', insertfocus)
    insertentries["Location"].bind('<Return>', insertfocus)
    insertentries["Tags"].bind('<Return>', getinsert)

def getinsert(event):
    for entry in insertentries:
        print (insertentries[entry].get())
        insertentries[entry].delete(0, 'end')
    insert.forget()
    mainmenu()

def insertfocus(event):
    currentnames.next()
    insertentries[currentnames].focus()

def insertform():
    i = 0

    for name in insertnames:
        e = tk.Entry(insert)
        e.grid(row = i, column = 1)
        insertentries[name] = e

        lab = tk.Label(insert, text = name)
        lab.grid(row = i, column = 0)
        insertlabels[name] = lab

        i += 1

insertbutton = tk.Button(main, text = "Insert", command = insertcall)
mainmenu()

tk.mainloop()

【问题讨论】:

    标签: python python-3.x tkinter


    【解决方案1】:

    您正在复制用于在一组小部件之间移动的 tab 键的功能。这使用虚拟事件&lt;&lt;NextWindow&gt;&gt;&lt;&lt;PrevWindow&gt;&gt;。所以要做的是让你的&lt;Return&gt; 处理程序生成这个事件。然后对于您要转到特定小部件的最后一个条目。我已经创建了一个这样做的例子。您可以将这样的东西与小部件集合一起使用,或者如果您深入了解 tk_focusNext 函数正在执行的操作以计算出下一个要转到的小部件,则可以安排检查包含框架中的小部件。

    编辑:通过从python生成遍历事件来模拟tk::TabToWindow函数

    import tkinter as tk
    
    class MyEntry(tk.Entry):
        """Entry widget with Return bound to provide tabbing functionality"""
        def __init__(self, master, **kw):
            tk.Entry.__init__(self, master, **kw)
            self.next_widget = None
            self.bind("<Return>", self.on_ret)
        def on_ret(self, ev):
            if self.next_widget:
                self.event_generate('<<TraverseOut>>')
                self.next_widget.focus()
                self.next_widget.event_generate('<<TraverseIn>>')
            else:
                self.event_generate('<<NextWindow>>')
            return "break"
        def set_next(self, widget):
            """Override the default next widget for this instance"""
            self.next_widget = widget
    
    def add_entry(parent, row, **kwargs):
        widget = MyEntry(parent, **kwargs)
        widget.grid(row=row, column=0, sticky=tk.NSEW)
        return widget
    
    def main(args=None):
        root = tk.Tk()
    
        frame = tk.LabelFrame(root, text="Entries", width=200, height=200)
    
        entries = []
        for row in range(4):
            e = add_entry(frame, row)
            entries.append(e)
        e.set_next(entries[0])
    
        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(0, weight=0)
    
        button = tk.Button(root, text="Exit", command=root.destroy)
    
        frame.grid(row=0, column=0, sticky=tk.NSEW)
        button.grid(row=1, column=0, sticky=tk.SE)
        root.grid_columnconfigure(0, weight=1)
        root.grid_rowconfigure(0, weight=1)
    
        entries[0].focus_set()
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      【解决方案2】:

      我知道这不是最好的选择,但一种冗长的方法是硬编码。对字典有更多经验的人可能可以循环执行,但我不能:)

      import tkinter as tk
      
      insertnames = ["Title", "Location", "Tags", "Section", "Blah"]
      obj = []
      
      root = tk.Tk()
      
      firstFrame = tk.Frame(root)
      entryFrame = tk.Frame(root)
      
      def mainmenu():
          firstFrame.pack()
          insertButton.pack(fill='x')
      
      def insertcall():
          firstFrame.forget()
          entryFrame.pack()
      
          title = tk.Entry(entryFrame)
          title.bind('<Return>', lambda event: focus(title))
          title.grid(row=0, column=1)
          obj.append(title)
          tk.Label(entryFrame, text='Title').grid(row=0, column=0)
      
          location = tk.Entry(entryFrame)
          location.bind('<Return>', lambda event: focus(location))
          location.grid(row=1, column=1)
          obj.append(location)
          tk.Label(entryFrame, text='Location').grid(row=1, column=0)
      
          tags = tk.Entry(entryFrame)
          tags.bind('<Return>', lambda event: focus(tags))
          tags.grid(row=2, column=1)
          obj.append(tags)
          tk.Label(entryFrame, text='Tags').grid(row=2, column=0)
      
          section = tk.Entry(entryFrame)
          section.bind('<Return>', lambda event: focus(section))
          section.grid(row=3, column=1)
          obj.append(section)
          tk.Label(entryFrame, text='Section').grid(row=3, column=0)
      
          blah = tk.Entry(entryFrame)
          blah.bind('<Return>', lambda event: focus(blah))
          blah.grid(row=4, column=1)
          obj.append(blah)
          tk.Label(entryFrame, text='Blah').grid(row=4, column=0)
      
      def focus(entryobj):
          i = 0
          for item in obj: #for each try and get next item unless it gives an error (then it must be the last entry so put it to 0)
              try:
                  if item == entryobj:
                      obj[i+1].focus_set()
                      break
              except IndexError:
                  obj[0].focus_set()
              i += 1
      
      insertButton = tk.Button(firstFrame, text='Insert', command=insertcall)
      insertButton.pack()
      
      mainmenu()
      
      root.mainloop()
      

      【讨论】:

      • 谢谢,这帮助很大。我仍然不熟悉 lambda,但我能够使用类似于示例中的 lambda 事件正确绑定 return。 insertentries[0].bind('&lt;Return&gt;', lambda event: insertfocus(insertentries[1])) 和新的插入焦点看起来像 def insertfocus(obj): obj.focus()
      【解决方案3】:

      您可以将相关条目小部件的 键绑定到如下函数:

      def entry_next(self, event):         
          event.widget.tk_focusNext().focus()
          return("break")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-08
        • 2012-11-17
        • 2021-11-08
        • 2020-09-24
        • 1970-01-01
        • 2017-12-27
        • 1970-01-01
        相关资源
        最近更新 更多