【问题标题】:Tkinter Format Text on Entry输入时的 Tkinter 格式文本
【发布时间】:2013-06-20 13:03:46
【问题描述】:

根据用户类型将文本格式化为时间格式

当用户输入数字时,我正在尝试在 Tk.Entry 文本框中将文本格式化为标准时间格式 00:00:00。

我知道 Tkinter 不是在用户键入时格式化文本的最简单、也不是最优化的框架,但我已经做到了这一点:

from Tkinter import *

class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()


    def createWidgets(self):
        sv = StringVar()
        sv.trace("w", lambda name, index, mode, sv=sv: self.entryUpdateEndHour(sv))
        endHourEntry = Entry(self, textvariable=sv)
        endHourEntry.pack()

    def entryUpdateEndHour(self, sv):
        global x

        x = sv.get()[0:2] + ':'
        y = x + sv.get()[3:5] + ':'
        z = y + sv.get()[6:8]

        sv.set(z)


root = Tk() 
app = Application(master=root) 
app.mainloop()

这会打印出我想要的 (12:45:67),但实时格式很糟糕。例如,在输入两个数字时,我在文本框中得到12:::,它会跳过我输入的每第三个数字,因为它会用: 替换它。

如果有人对此答案有任何解决方法或解决方案,我将不胜感激。提前致谢。

【问题讨论】:

  • 您的代码块中有一些未定义的变量:self、entryUpdateEndHour、svEndHour。您能否提供一个short, self-contained, runnable example,我们可以复制/粘贴/运行?
  • @Kevin 我已经让我的代码可以运行,所以我的问题现在应该更容易回答了。

标签: python textbox tkinter string-formatting live-update


【解决方案1】:

这是我的解决方案:

from Tkinter import *

class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        sv = StringVar()
        endHourEntry = Entry(self, textvariable=sv)
        sv.trace("w", lambda name, index, mode, sv=sv: 
                             entryUpdateEndHour(endHourEntry))
        endHourEntry.pack()

def entryUpdateEndHour(entry):
    text = entry.get()
    if len(text) in (2,5):
        entry.insert(END,':')
        entry.icursor(len(text)+1)
    elif len(text) not in (3,6):
        if not text[-1].isdigit():
            entry.delete(0,END)
            entry.insert(0,text[:-1])
    if len(text) > 8:
        entry.delete(0,END)
        entry.insert(0,text[:8])


root = Tk() 
app = Application(master=root) 
app.mainloop()

对我来说,使用入口小部件而不是直接使用 StringVar 更容易。完全包含 stringvar 的唯一原因是获取跟踪行为,以便正确调用回调。另一种选择是使用 vcmd option 对 Entry 构造函数做一些事情,但我似乎无法更新条目...仅验证内容。

【讨论】:

    【解决方案2】:
    from Tkinter import *
    
    class Application(Frame):
        def __init__(self, master=None):
            Frame.__init__(self, master)
            self.pack()
            self.createWidgets()
    
    
        def createWidgets(self):
            sv = StringVar()
            sv.trace("w", lambda name, index, mode, sv=sv: self.entryUpdateEndHour(sv))
            self.endHourEntry = Entry(self, textvariable=sv)
            self.endHourEntry.pack()
            print [x for x in dir(self.endHourEntry) if 'set' in x]
    
        def entryUpdateEndHour(self, sv):
            digits = filter(str.isdigit, sv.get())
            sv.set('{}:{}:{}'.format(digits[:2], digits[2:4], digits[4:]))
            self.endHourEntry.icursor(END)
    
    
    root = Tk() 
    app = Application(master=root) 
    app.mainloop()
    

    问题:光标总是走到结尾。我对此没有好主意。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多