【问题标题】:How to make specific text non-removable in tkinter?如何在 tkinter 中使特定文本不可删除?
【发布时间】:2020-12-31 13:56:24
【问题描述】:

我有一个关于 Tkinter 文本和条目小部件的快速问题。 如何使特定文本不可删除? 是的,我知道.config(state="disabled"),不,这不是我想要的,它只是让所有文本都无法删除。

假设我有一个文本框。在该文本框中有一个“输入消息”文本。 用户可以像任何其他文本框一样键入和删除。但是,我不希望用户删除“输入消息”。

就像在 Windows shell 中你不能删除 "C:\Users\your username>" 或您所在的任何目录。

这里有一些代码:

from tkinter import *

root = Tk()
root.geometry("500x500")
entry = Entry(root, bg="black", fg="white")
entry.pack(side="top", fill="x")
entry.insert(END, "Enter message: ")
entry.non_removable("Enter message: ") # << not a real code. just what i imagine it to be

mainloop()

【问题讨论】:

  • @Atlas435:这是用于文本小部件的。这个问题是关于 Entry 小部件的。这两个小部件具有非常不同的功能。
  • @BryanOakley 关于 Tkinter 文本和条目小部件。 是 OP 的问题。我认为您提供的代码可以通过一些调整来创建一个服装条目。
  • @Atlas435:好的。是的,开头段落提到了一个Text 小部件,但代码并没有创建一个。感谢您指出这一点。

标签: python-3.x tkinter


【解决方案1】:

另一种方法是使用验证。

def do_validate( text ):
    # if this returns False the entered key(s) aren't accepted.
    return text.startswith( "Enter message: " )

import tkinter as tk

root = tk.Tk()
root.geometry("500x500")
entry = tk.Entry(root, bg="black", fg="white")
entry.pack(side="top", fill="x")
entry.insert( tk.END, "Enter message: ")

validate_cmd = ( root.register( do_validate ), '%P' )
entry.config( validate = 'key', validatecommand = validate_cmd )

root.mainloop()

如果按键创建的字符串不是以“Enter Message:”开头,则按键被拒绝并且条目文本不变。

【讨论】:

    【解决方案2】:

    执行此操作的最简单方法是通过绑定并在文本与您的文本匹配时返回“break”来禁用退格,并在不匹配时取消绑定。

    这里试试这个:

    from tkinter import *
    
    def check(*args):
       
        if entry.index(INSERT) <= len("Enter message: "):
            entry.bind('<BackSpace>', lambda _:'break')
            
        else:
            entry.unbind('<BackSpace>')
                
        
    root = Tk()
    root.geometry("500x500")
    
    var = StringVar()
    var.trace('w', check)
    
    entry = Entry(root, textvariable=var)
    entry.pack(side="top", fill="x")
    entry.insert(END, "Enter message: ")
    
    mainloop()
    
    

    更新 如果用户使用鼠标选择并将其删除,上述代码将失败。所以你必须清除选择。

    这里用这个

    from tkinter import *
    
    def check(*args):
        
        if entry.index(INSERT) <= len("Enter message: "):
            entry.bind('<BackSpace>', lambda _:'break')
            entry.bind('<Delete>', lambda _:'break')
            entry.bind('<Shift-.>', lambda _:'break')
            if entry.select_present():
                entry.select_clear()
            
        else:
            entry.unbind('<BackSpace>')
            entry.unbind('<Delete>')
            entry.unbind('<Shift-.>')
        
    root = Tk()
    root.geometry("500x500")
    
    var = StringVar()
    var.trace('w', check)
    
    entry = Entry(root, textvariable=var)
    entry.pack(side="top", fill="x")
    entry.insert(END, "Enter message: ")
    entry.bind('<ButtonRelease>', check)
    
    mainloop()
    

    好的,我找到了另一个万无一失的解决方法:

    from tkinter import *
    
    def check(*args):
        global old_var
    
        if var.get()[:15] != check_string:
            var.set(old_var)
    
        else:
            old_var=var.get()
         
        
    root = Tk()
    root.geometry("500x500")
    
    check_string = "Enter message: "
    
    var = StringVar()
    var.set(check_string)
    
    var.trace('w', check)
    old_var = check_string
    
    entry = Entry(root, textvariable=var)
    entry.pack(side="top", fill="x")
    
    mainloop()
    

    工作: 创建一个临时变量。说old_var。最初将varold_var 分配给相同的字符串。使用trace 方法检测文本的变化。现在比较新更改的文本是否包含字符串。如果不包含字符串,则将其设置为旧字符串,如果确实将old_var 设置为var.get()

    您可以使用上述任何代码,以适合您的方式

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多