python - 用 `validatecommand` 选项替换 ttk.Entry 小部件中的选定条目
问题描述
以下脚本创建了一个ttk.Entry
小部件,它只接受可以转换为浮点类型的条目。当我使用鼠标指针选择键入的条目,然后按新的数字条目时,我希望新的数字条目替换选定的条目。目前这种行为不会发生。相反,新的数字条目将出现在所选数字的左侧。如何获得我需要的替换行为?
import tkinter as tk # python 3.x
import tkinter.ttk as ttk # python 3.x
class Example(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# %P = value of the entry if the edit is allowed
# %S = the text string being inserted or deleted, if any
vcmd = (self.register(self.onValidate),'%P', '%S')
self.entry = ttk.Entry(self, validate="key", validatecommand=vcmd)
self.entry.pack(side="top", fill="x")
def onValidate(self, P, S):
# Disallow anything but '0123456789.+-'
if S in '0123456789.+-':
try:
float(P)
print('float(P) True')
return True
except ValueError:
print('float(P) False')
return False
else:
print('S in 0123456789.+- False')
return False
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
更新:使用事件.bind
上的方法'<ButtonRelease>'
,我发现ttk.Entry
小部件中选择的类型条目可以通过该.selection_get()
方法获得。但是,我还没有弄清楚如何将这些方法联系起来以获得所需的行为。
将这些句子附加到__init__()
方法的末尾。
self.entry.bind( '<ButtonRelease>', self.selecttext )
def selecttext(self, event):
try:
print( 'selection = ', self.entry.selection_get() )
except tk.TclError:
pass
解决方案
发生的事情是这样的:当你选择一个文本范围然后按下一个键时,tkinter 必须做两件事:它必须删除选定的文本,然后它必须插入新的文本。
首先调用处理程序进行删除。因为删除导致条目小部件完全为空,并且您无法将空字符串转换为浮点数,所以您的处理程序返回False
. 这可以防止删除发生。
接下来,调用您的处理程序进行插入。旧文字还在。您允许插入,因此您最终得到的结果是所选文本不会被删除,新文本会插入到它之前。
最简单的解决方案是允许一个空字符串。然后,您可以简单地验证非空字符串是否可以转换为浮点数。
例子:
import tkinter as tk # python 3.x
import tkinter.ttk as ttk # python 3.x
class Example(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# %P = value of the entry if the edit is allowed
vcmd = (self.register(self.onValidate),'%P')
self.entry = ttk.Entry(self, validate="key", validatecommand=vcmd)
self.entry.pack(side="top", fill="x")
def onValidate(self, P):
if P.strip() == "":
# allow blank string
return True
try:
float(P)
return True
except:
return False
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
推荐阅读
- amazon-web-services - 如何为 Amazon aws ec2 centos 7.5 实例增加 /var 的大小
- amazon-web-services - Amazon S3 同步命令再次上传整个修改后的文件还是仅上传文件中的增量?
- mysql - mysql多组和下单很慢
- css - 角度动画:填充不以高度 0->* 进行动画处理
- excel - 如何更改字符 laravel excel maatwebsite 的颜色?
- php - 将 Laravel 5.4 升级到 5.6 的问题
- php - 在 PHP 中将 Google Charts p 属性添加到 JSON
- c - 猜谜游戏 - 无法弄清楚为什么它会产生一个大的负整数
- visual-studio-2015 - 由于 SSL,Visual Studio nuget 失败
- git - 如何执行不检查遥控器的 Git 状态?