【问题标题】:First letter in tkinter Entry box is not being deletedtkinter 输入框中的第一个字母没有被删除
【发布时间】:2021-08-12 23:08:29
【问题描述】:

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

这是我的简化问题。

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()

【问题讨论】:

  • 你的缩进错误。
  • @Derek:缩进在句法上是有效的——但是它非常规并且不是很可读。
  • 只是想知道,您的问题是否已得到解决和回答?

标签: python validation tkinter tkinter-entry


【解决方案1】:

它不允许你删除最后一个数字的原因是因为这使得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()

【讨论】:

  • @Vorbeker:FWIW,这是 another way 做这样的事情,虽然不像为 Entry 小部件注册验证回调那样通用,但确实具有更简单的优点。跨度>
【解决方案2】:

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

我添加了一个Button,以便focusout 有一些关注点。

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

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

is:在 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()

【讨论】:

  • IMO 最好解释一下为什么validate 更改为'focusout 可以解决问题(或者它在这样做中发挥了什么作用)而不是建议他们搜索整个互联网以获取更多信息。
  • 我误解了你关于搜索的建议,但即使“只有”那么多匹配项也相当多,所以我所说的要点和我对不自己解释事情的其他批评是有效的- 你的更新是一个改进。顺便说一句,您可以将搜索格式化为this 之类的链接。
猜你喜欢
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 2020-09-12
  • 2018-11-09
相关资源
最近更新 更多