我正在尝试为日期创建一个简单的TextInput,以将输入限制为数字,并自动填充(mm / dd / yy)格式的正斜杠。我成功创建了一个通过重新定义insert_text()来实现此目的的过滤器,但当用户退格时,我也想自动删除斜杠。但是我不知道如何检测文本输入中用户何时退格,以便在必要时触发事件以消除斜杠。
这是一个片段,解释了我想要做什么,但是TextInput没有“ on_key_up”属性。有没有办法添加一个?还是解决这个问题的更好方法?
# .kv file
<DateInput>
on_key_up: self.check_for_backspace(keycode) # not a true attribute
# .py file
class DateInput(TextInput):
# checks if last character is a slash and removes it after backspace keystroke. Not sure this would work.
def check_for_backspace(self, keycode):
if keycode[1] == 'backspace' and self.text[-1:] == '/':
self.text = self.text[:-1]
#filter for date formatting which works well aside from backspacing
pat = re.compile('[^0-9]')
def insert_text(self, substring, from_undo=False):
pat = self.pat
if len(substring) > 1:
substring = re.sub(pat, '', (self.text + substring))
self.text = ''
slen = len(substring)
if slen == 2:
s = substring[:2] + '/'
elif slen == 3:
s = substring[:2] + '/' + substring[2:]
elif slen == 4:
s = substring[:2] + '/' + substring[2:] + '/'
else:
s = substring[:2] + '/' + substring[2:4] + '/' + substring[4:8]
elif len(self.text) > 9:
s = ''
elif len(self.text) == 1:
s = re.sub(pat, '', substring)
if s != '':
s = s + '/'
elif len(self.text) == 4:
s = re.sub(pat, '', substring)
if s != '':
s = s + '/'
else:
s = re.sub(pat, '', substring)
return super(DateInput, self).insert_text(s, from_undo=from_undo)
答案 0 :(得分:0)
由于1。TextInput
版本是FocusBehavior
固有的,因此,如果要检测何时按退格键,必须使用keyboard_on_key_down()
方法或keyboard_on_key_up()
方法:< / p>
from kivy.app import App
from kivy.uix.textinput import TextInput
class DateInput(TextInput):
def keyboard_on_key_down(self, window, keycode, text, modifiers):
if keycode[1] == "backspace":
print("print backspace down", keycode)
TextInput.keyboard_on_key_down(self, window, keycode, text, modifiers)
def keyboard_on_key_up(self, window, keycode, text, modifiers):
if keycode[1] == "backspace":
print("print backspace up", keycode)
TextInput.keyboard_on_key_down(self, window, keycode, text, modifiers)
class MyApp(App):
def build(self):
return DateInput()
if __name__ == '__main__':
MyApp().run()
答案 1 :(得分:0)
这里是想要自动格式化日期输入的任何人的完整解决方案:
class DateInput(TextInput):
def keyboard_on_key_up(self, window, keycode):
if keycode[1] == "backspace" and len(self.text) >= 1:
if self.text[-1] == "/":
self.text = self.text[:-1]
else:
pass
else:
pass
TextInput.keyboard_on_key_up(self, window, keycode)
pat = re.compile('[^0-9]')
def insert_text(self, substring, from_undo=False):
pat = self.pat
if len(substring) > 1:
substring = re.sub(pat, '', (self.text + substring))
self.text = ''
slen = len(substring)
if slen == 2:
s = substring[:2] + '/'
elif slen == 3:
s = substring[:2] + '/' + substring[2:]
elif slen == 4:
s = substring[:2] + '/' + substring[2:] + '/'
else:
s = substring[:2] + '/' + substring[2:4] + '/' + substring[4:8]
elif len(self.text) > 9:
s = ''
elif len(self.text) == 2:
s = re.sub(pat, '', substring)
if s != '':
s = '/' + s
elif len(self.text) == 5:
s = re.sub(pat, '', substring)
if s != '':
s = '/' + s
else:
s = re.sub(pat, '', substring)
return super(DateInput, self).insert_text(s, from_undo=from_undo)
答案 2 :(得分:0)
在TextInput中重写do_backspace()
方法。如果文本为“ /”,则返回True,表示我们已经消耗了退格键,并且不希望它进一步传播。
最后,如果文本不是'/',我们使用super(…)调用原始事件并返回结果。这样可以使do_backspace事件传播继续正常进行。
请参阅示例。
Text Input » do_backspace() method
do_backspace(from_undo=False, mode='bkspc')
从当前光标位置开始退格操作。这个动作 可能会做几件事:
- 删除当前选择(如果可用)。
- 删除上一个字符并将光标移回。
- 如果我们刚开始,什么也不要做。
from kivy.app import App
from kivy.uix.textinput import TextInput
import re
class DateInput(TextInput):
def do_backspace(self, from_undo=False, mode='bkspc'):
print(from_undo, mode)
if len(self.text) >= 1:
if self.text[-1] == "/":
self.text = self.text[:-1]
return True # we have consumed the backspace and don’t want it to propagate any further
return super(DateInput, self).do_backspace(from_undo, mode)
#filter for date formatting which works well aside from backspacing
pat = re.compile('[^0-9]')
def insert_text(self, substring, from_undo=False):
pat = self.pat
if len(substring) > 1:
substring = re.sub(pat, '', (self.text + substring))
self.text = ''
slen = len(substring)
if slen == 2:
s = substring[:2] + '/'
elif slen == 3:
s = substring[:2] + '/' + substring[2:]
elif slen == 4:
s = substring[:2] + '/' + substring[2:] + '/'
else:
s = substring[:2] + '/' + substring[2:4] + '/' + substring[4:8]
elif len(self.text) > 9:
s = ''
elif len(self.text) == 1:
s = re.sub(pat, '', substring)
if s != '':
s = s + '/'
elif len(self.text) == 4:
s = re.sub(pat, '', substring)
if s != '':
s = s + '/'
else:
s = re.sub(pat, '', substring)
return super(DateInput, self).insert_text(s, from_undo=from_undo)
class TestApp(App):
def build(self):
return DateInput()
if __name__ == "__main__":
TestApp().run()
答案 3 :(得分:0)
这是我的解决方案:
class DateInput(TextInput):
pat = re.compile("[^0-9]")
def insert_text(self, substring, from_undo=False):
pat = self.pat
s = re.sub(pat, "", substring)
if len(self.text) >= 10:
return super(DateInput, self).insert_text("", from_undo=from_undo)
elif ((len(self.text) > 2) and (self.cursor_index() == 2)) or (
(len(self.text) > 5) and (self.cursor_index() == 5)
):
return super(DateInput, self).insert_text("/", from_undo=from_undo)
elif (len(self.text) == 2) or (len(self.text) == 5):
return super(DateInput, self).insert_text("/" + s, from_undo=from_undo)
else:
return super(DateInput, self).insert_text(s, from_undo=from_undo)