用户输入后在条目小部件上调用delete()

时间:2019-05-02 12:59:35

标签: python tkinter tkinter-entry

我想在用户输入后在我的delete()小部件上调用Entry,但这会导致AttributeError

我已经尝试调试自己,无法弄清AttributeError的来源。

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from datetime import *

class Main(ttk.Frame):
    def __init__(self, parent):
        super().__init__()

        self.parent = parent

        self.punches_list = []
        self.ent = tk.StringVar()

        self.ui_init()

    def ui_init(self):

        f = ttk.Frame()
        ttk.Label(f, text = "Entry").pack(padx=5, pady=5)
        self.txTest = ttk.Entry(f, textvariable=self.ent).pack()
        self.lstItems = self.get_listbox(f, 30,50)
        w = ttk.Frame()

        ttk.Button(w, text="Punch In",command=self.punch_In).pack(padx=4, pady=5)
        ttk.Button(w, text="Punch Out", command=self.punch_Out).pack(padx=5, pady=5)
        ttk.Button(w, text="Close", command=self.on_close).pack(padx=5, pady=5)

        f.pack(side=tk.LEFT, fill=tk.BOTH, expand=1, padx=5, pady=5)
        w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)

    def punch_In(self,):
        s = "IN {0:>30} {1}".format(str(datetime.now()), self.ent.get())
        self.set_list(s)
        self.ent.delete(0, tk.END)

    def punch_Out(self):
        s = "OUT {0:>29} {1}".format(str(datetime.now()), self.ent.get())
        self.set_list(s)

    def set_list(self,s):

        self.punches_list.append(s)

        self.lstItems.delete(0, tk.END)
        for i in self.punches_list:
            self.lstItems.insert(tk.END, i)

    def on_set(self):

        self.check.set(1)

    def on_close(self):
        self.parent.on_exit()

    def get_listbox(self, container, height=None, width=None):

        sb = tk.Scrollbar(container,orient=tk.VERTICAL)

        w = tk.Listbox(container,
                relief=tk.RIDGE,
                selectmode=tk.BROWSE,
                height=height,
                width=width,
                background = 'white',
                font='TkFixedFont',
                yscrollcommand=sb.set,)

        sb.config(command=w.yview)

        w.pack(side=tk.LEFT,fill=tk.BOTH, expand =1)
        sb.pack(fill=tk.Y, expand=1)
        return w

class App(tk.Tk):
    """Start here"""

    def __init__(self):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.on_exit)

        self.set_style()
        self.set_title()
        Main(self,)

    def set_style(self):
        self.style = ttk.Style()
        #('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
        self.style.theme_use("clam")

    def set_title(self):
        s = "{0}".format('Timekeeping')
        self.title(s)

    def on_exit(self):
        """Close all"""
        if messagebox.askokcancel( self.title(), "Do you want to quit?", parent=self):
        self.destroy()

if __name__ == '__main__':
    app = App()
    app.mainloop()

这是回溯:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "C:\users\steven\documents\github\tkinterapp\happy.py", line 39, in punch_In
    self.ent.delete(0, tk.END)
AttributeError: 'StringVar' object has no attribute 'delete'

1 个答案:

答案 0 :(得分:2)

严格来说,您不会在条目窗口小部件上调用delete,因为self.ent是StringVar,而不是条目。如果需要访问Entry对象,请尝试使用self.txTest

self.txTest.delete(0, tk.END)

但是首先,请确保将Entry对象实际分配给self.txTest,而不是像现在这样分配Entry.pack()的结果。更改此:

self.txTest = ttk.Entry(f, textvariable=self.ent).pack()

对此:

self.txTest = ttk.Entry(f, textvariable=self.ent)
self.txTest.pack()

或者,您可能希望仅继续使用self.ent来操纵条目的内容。毕竟,StringVar的卖点之一是为Entry对象提供简化的接口,不需要您直接与Entry直接交互。您可以通过使用空字符串调用set来擦除StringVar和Entry的内容。

def punch_In(self,):
    s = "IN {0:>30} {1}".format(str(datetime.now()), self.ent.get())
    self.set_list(s)
    self.ent.set("")