Tkinter text field with limited number of availabale character
I'm working on an applicati开发者_StackOverflow中文版on to edit DNA sequences and I'd like to have a tkinter text widget in which only letters atgcATGC can be entered.
Is there any easy way to do that?
Thanks, David
You can use the validatecommand
feature of the Entry
widget. The best documentation I can find is this answer to a similar question. Following that example,
import Tkinter as tk
class MyApp():
def __init__(self):
self.root = tk.Tk()
vcmd = (self.root.register(self.validate), '%S')
self.entry = tk.Entry(self.root, validate="key",
validatecommand=vcmd)
self.entry.pack()
self.root.mainloop()
def validate(self, S):
return all(c in 'atgcATGC' for c in S)
app=MyApp()
I finally found a way to have the exact behavior I want:
from Tkinter import Text, BOTH
import re
class T(Text):
def __init__(self, *a, **b):
# Create self as a Text.
Text.__init__(self, *a, **b)
#self.bind("<Button-1>", self.click)
self.bind("<Key>", self.key)
self.bind("<Control-v>", self.paste)
def key(self,k):
if k.char and k.char not in "atgcATGC":
return "break"
def paste(self,event):
clip=self.selection_get(selection='CLIPBOARD')
clip=clip.replace("\n","").replace("\r","")
m=re.match("[atgcATGC]*",clip)
if m and m.group()==clip:
self.clipboard_clear()
self.clipboard_append(clip)
else:
self.clipboard_clear()
return
t = T()
t.pack(expand=1, fill=BOTH)
t.mainloop()
You will have to catch the "<Key>"
event on the widget where you're entering text. Then you can just filter
if key.char and key.char not in "atgcATGC":
return "break"
Here's some info on handling events in tkinter: http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
I would recommend the Pmw toolkit which provides a lot of handy extras to Tkinter. The Pmw EntryField class allows you to write an arbitrary validator for any text field. Pmw is lightweight and very usable, if you are developing anything in Tkinter you will probably find its features useful.
精彩评论