【问题标题】:Tkinter - Entry box - formatted for dateTkinter - 输入框 - 格式化为日期
【发布时间】:2021-09-02 10:26:10
【问题描述】:

我想要一个输入日期的输入框,以便用户只能以一种方式输入。

输入前的输入框看起来像这样(不带下划线)__/__/____,当用户输入日期。

谢谢

【问题讨论】:

  • @Tim 我假设 OP 想要这样一个输入框。
  • 我不相信这是可能的。
  • @pydsigner:当然有可能。单个条目小部件不直接支持它,但我已经看到它完成了。只需要三个条目小部件、两个标签小部件和一些特殊绑定。
  • @Bryan Oakley 啊!我现在可以想象这件事了……我在考虑一个 Entry()。

标签: python date tkinter


【解决方案1】:

感谢@Bryan Oakley 的主要提示,我想出了这个工作代码。

(更新:投入了几年的编程经验和一些最近的读者对改进代码的敏锐眼光。)

from __future__ import print_function

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


class DateEntry(tk.Frame):
    def __init__(self, master, frame_look={}, **look):
        args = dict(relief=tk.SUNKEN, border=1)
        args.update(frame_look)
        tk.Frame.__init__(self, master, **args)

        args = {'relief': tk.FLAT}
        args.update(look)

        self.entry_1 = tk.Entry(self, width=2, **args)
        self.label_1 = tk.Label(self, text='/', **args)
        self.entry_2 = tk.Entry(self, width=2, **args)
        self.label_2 = tk.Label(self, text='/', **args)
        self.entry_3 = tk.Entry(self, width=4, **args)

        self.entry_1.pack(side=tk.LEFT)
        self.label_1.pack(side=tk.LEFT)
        self.entry_2.pack(side=tk.LEFT)
        self.label_2.pack(side=tk.LEFT)
        self.entry_3.pack(side=tk.LEFT)

        self.entries = [self.entry_1, self.entry_2, self.entry_3]

        self.entry_1.bind('<KeyRelease>', lambda e: self._check(0, 2))
        self.entry_2.bind('<KeyRelease>', lambda e: self._check(1, 2))
        self.entry_3.bind('<KeyRelease>', lambda e: self._check(2, 4))

    def _backspace(self, entry):
        cont = entry.get()
        entry.delete(0, tk.END)
        entry.insert(0, cont[:-1])

    def _check(self, index, size):
        entry = self.entries[index]
        next_index = index + 1
        next_entry = self.entries[next_index] if next_index < len(self.entries) else None
        data = entry.get()

        if len(data) > size or not data.isdigit():
            self._backspace(entry)
        if len(data) >= size and next_entry:
            next_entry.focus()

    def get(self):
        return [e.get() for e in self.entries]


if __name__ == '__main__':        
    win = tk.Tk()
    win.title('DateEntry demo')

    dentry = DateEntry(win, font=('Helvetica', 40, tk.NORMAL), border=0)
    dentry.pack()

    win.bind('<Return>', lambda e: print(dentry.get()))
    win.mainloop()

【讨论】:

  • 如果将入口小部件的边框宽度设置为零,然后将所有小部件放在边框宽度为 1(一)的框架中,它看起来就像一个小部件。否则,出色的工作。不要将 Tkinter 视为小部件的集合,而应将其视为一盒乐高积木。
  • 哇。 不是我想要的,而是超越它。感谢您投入时间!谢谢@pydsigner 和@Bryan!你们摇滚:D
  • 我有时在三种检查方法中得到IndexError(由于空字段)。我通过将所有内容包装在这些方法 if cont: 中解决了这个问题。
  • 对于 Python 3,只需编辑第 1 行,将 'Tkinter' 更改为 'tkinter',还有第 69 行,在 print 语句周围添加括号: print(dentry.get())
  • @Inyoka 更新后的代码应该适用于 Python 2 和 3。
【解决方案2】:

我发现了一个非常简单的解决方案。我希望有人能发现它有用。

self.entry1=tk.Entry(self)
self.entry1.insert(END, "    /    /        ")
self.entry1.config(fg="grey")

def datemask(self, event):
if len(self.entry1.get()) is 2:
    self.entry1.insert(END,"/")

elif len(self.entry1.get()) is 5:
    self.entry1.insert(END,"/")

elif len(self.entry1.get()) is 11:
    self.entry1.delete(10, END)

绑定入口小部件

self.entry1.bind('<KeyRelease>', self.datemask)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    • 2013-11-14
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多