tkinter 输入框中的第一个字母未被删除

First letter in tkinter Entry box is not being deleted

我正在制作一个 tkinter 程序,我希望将用户输入限制为仅浮点数。我使用 register 和验证功能完成了此操作。所有这些都工作正常,但是当我输入一组数字时,程序不允许我删除第一个。我认为这与我 class 中的最终函数有关,但我不知道如何在不破坏程序其余部分的情况下对其进行编辑。

这是我简化的问题。

from tkinter import *

class investables(Frame):

 def __init__(self, master):
    Frame.__init__(self, master=None)
    self.pack()
    self.master = master
    
    vcmd = (master.register(self.validate),'%d', '%i', '%P', '%s', 
           '%S', '%v', '%V', '%W')
    self.entry1 = Entry(self, validate="key", validatecommand=(vcmd))
    self.entry1.grid(row=1, column=3)

    # Define validate function, this also passes the many components 
    # of the register tool
 def validate(self, d, i, P, s, S, v, V, W):
    # Begin if else statement that prevents certain user input
    if P:
        try:
            # Checks if %P is a float
            float(P)
            # If this is the case then the input is excepted
            return True
        # If this is not the case, then the code will not accept user 
        # input
        except ValueError:
            return False
    # If any other input is inserted, the program will not accept it 
     # either    
    else:
         return False

root = Tk()
my_gui = investables(master=root)
my_gui.mainloop()

我将 validate 更改为 focusout 因为您需要能够在 Entry 小部件中输入浮点数 验证之前.

我添加了一个 Button 以便 focusout 有重点。

validate“键”的使用只允许单键输入,这显然会阻止输入浮点数。

有关更多信息,请尝试使用堆栈溢出搜索工具并输入以下内容。

是:交互式验证 tkinter 中的 Entry 小部件内容

这将为您提供多个可能对您有用的问题和答案。

import tkinter as tk

class investables(tk.Frame):

    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.pack(fill="both", expand=True)

        vcmd = (master.register(self.validate),
                '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.entry1 = tk.Entry(self, validate = "focusout", validatecommand = vcmd)
        self.entry1.pack(side = "left", fill = "both", expand = True)
        self.ok = tk.Button(self, text = "Ok", command = self.action)
        self.ok.pack(side = "right", fill = "both", expand = True)
        self.entry1.focus()

    def action( self ):
        self.ok.focus()

    def validate(self, d, i, P, s, S, v, V, W):
        try:
            if repr(float(P)) == P:
                print( "Validation successful" )
                return True
            else:            
                print( "Validation Failed" )
                return False
        except ValueError:
            print( "Validation Failed" )
            return False

root = tk.Tk()
my_gui = investables(master = root)
root.mainloop()

它不会让你删除最后一位数字的原因是因为这使得 P 等于空字符串 "",这将导致 float("") 引发 ValueError 异常——所以最小的修复是修改你的代码以接受 P 当它是那个值时。

下面展示了一种方法。我还简化了您的一些内容并重新格式化以在某种程度上遵循 PEP 8 - Style Guide for Python Code 准则。我强烈建议您自己阅读并开始关注它们——这将使您的代码更具可读性和更易于维护。

from tkinter import Entry, Frame, Tk


class Investables(Frame):
    def __init__(self, master):
        super().__init__(master)  # Initialize base class.
        self.pack()

        vcmd = (master.register(self.validate),
                '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.entry1 = Entry(self, validate="key", validatecommand=vcmd)
        self.entry1.grid(row=1, column=3)

    # Define validate function, this receives the many components specified when
    # the registering the function (even though only `P` is used).
    def validate(self, d, i, P, s, S, v, V, W):
        if P: # Check the value that the text will have if the change is allowed.
            try:
                float(P)  # Checks if %P is a float
            except ValueError:  # Don't accept user input.
                return False
        return True  # Note this will consider nothing entered as valid.


if __name__ == '__main__':
    root = Tk()
    my_gui = Investables(master=root)
    my_gui.mainloop()