Я использую Python 2.7 и KIVY.Когда я нажимаю за пределами Text
в TextInput
, я не могу печатать.Может ли кто-нибудь помочь мне, что когда я нажимаю textInput
, как установить или сдвинуть cursor
конец текста?Я использую instance.cursor = (len(instance.text), 0)
в def on_focus()
для установки положения курсора, но он не работает.
test.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.uix.textinput import TextInput
from kivy.properties import BooleanProperty, ListProperty, ObjectProperty, NumericProperty, DictProperty, StringProperty
Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (400, 50)
class RightFloatInput(TextInput):
decimal = NumericProperty(0)
negative = False
def __init__(self, **kwargs):
super(RightFloatInput, self).__init__(**kwargs)
self.multiline = False
def right_adjust(self, text):
max_width = self.width - self.padding[0] - self.padding[2]
new_text = text.strip()
text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
while text_width < max_width:
new_text = ' ' + new_text
text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
while text_width >= max_width:
if new_text != ' ':
break
else:
new_text = new_text[1:]
text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
return new_text.rstrip()
def on_size(self, instance, value):
super(RightFloatInput, self).on_size(instance, value)
if len(self._lines) == 0:
return True
cc, cr = self.cursor
cur_text = self._lines[cr]
initial_len = len(cur_text)
super(RightFloatInput, self)._refresh_text(self.right_adjust(cur_text))
final_len = len(self._lines[cr])
self.cursor = self.get_cursor_from_index(final_len - (initial_len - cc))
return
def delete_selection(self, from_undo=False):
# print('delete_selection')
if not self._selection:
return
cr = self.cursor[1]
initial_len = len(self._lines[cr])
a, b = self._selection_from, self._selection_to
if a > b:
a, b = b, a
super(RightFloatInput, self).delete_selection(from_undo=from_undo)
cur_text = self._lines[cr]
super(RightFloatInput, self)._refresh_text(self.right_adjust(cur_text))
final_len = len(self._lines[cr])
self.cursor = self.get_cursor_from_index(final_len - (initial_len - b))
def do_backspace(self, from_undo=False, mode='bkspc'):
# print('do_backspace')
cc, cr = self.cursor
initial_len = len(self._lines[cr])
super(RightFloatInput, self).do_backspace(from_undo=from_undo, mode=mode)
cc, cr = self.cursor
cur_text = self._lines[cr]
super(RightFloatInput, self)._refresh_text(self.right_adjust(cur_text))
final_len = len(self._lines[cr])
self.cursor = self.get_cursor_from_index(final_len - (initial_len - cc) + 1)
def insert_text(self, the_text, from_undo=False):
if self.readonly == True:
return
cc, cr = self.cursor
cur_text = self._lines[cr]
initial_len = len(cur_text)
new_text = self.right_adjust(cur_text[:cc] + the_text + cur_text[cc:])
try:
if self.negative == True:
if str(the_text) != "-":
num = float(new_text) # throw exception if new_text is invalid float
else:
num = float(new_text)
except ValueError:
return
if str(the_text) != "-":
if num > 10000000:
return
self._lines[cr] = ''
self._refresh_text(self.right_adjust(new_text))
final_len = len(self._lines[cr])
self.cursor = self.get_cursor_from_index(final_len - (initial_len - cc))
def set_right_adj_text(self, text):
self._refresh_text(self.right_adjust(text))
def on_focus(self, instance, isFocused):
if isFocused:
final_len = len(instance.text)
instance.cursor = self.get_cursor_from_index(final_len)
Clock.schedule_once(lambda dt: self.selected_text())
if instance.focus:
self.cursor = (final_len, 0)
print("TextInput is focused [focus={}]".format(instance.focus))
instance.cursor = (len(instance.text), 0)
Clock.schedule_once(lambda dt: instance.select_all())
return
else:
try:
num = float(self.text.strip()) # throw exception if new_text is invalid float
except ValueError:
return
new_text = self.text.strip()
new_text = self.right_adjust(new_text)
self._refresh_text(new_text)
final_len = len(new_text)
self.cursor = self.get_cursor_from_index(final_len)
def on_touch_down_2(self, instanse):
final_len = len(self.text)
self.cursor = self.get_cursor_from_index(final_len)
return False
def selected_text(self):
ci = self.cursor_index()
cc = self.cursor_col
line = self._lines[self.cursor_row]
len_line = len(line)
start = max(0, len(line[:cc]) - line[:cc].rfind(u' ') - 1)
end = line[cc:].find(u' ')
end = end if end > - 1 else (len_line - cc)
Clock.schedule_once(lambda dt: self.select_text(ci - start, ci + end))
def on_text(self, instance, text):
if text.count('-') > 1:
self.text = "-"
return
new_text = self.right_adjust(text)
self._refresh_text(new_text)
final_len = len(new_text)
self.cursor = self.get_cursor_from_index(final_len)
def on_text_validate_old(self):
try:
num = float(self.text.strip()) # throw exception if new_text is invalid float
except ValueError:
return
if self.decimal == 1 and self.text.strip() != "":
self.text = str("{0:.1f}".format(float(self.text.strip())))
if self.decimal == 2 and self.text.strip() != "":
self.text = str("{0:.2f}".format(float(self.text.strip())))
if self.decimal == 3 and self.text.strip() != "":
self.text = str("{0:.3f}".format(float(self.text.strip())))
new_text = self.right_adjust(self.text)
self._refresh_text(new_text)
final_len = len(new_text)
self.cursor = self.get_cursor_from_index(final_len)
class abc(BoxLayout):
pass
class Test(App):
def build(self):
return abc()
if __name__ == '__main__':
Test().run()
test.kv
<abc>:
BoxLayout:
orientation: "vertical"
size_hint_y: .5
BoxLayout:
orientation: "horizontal"
spacing: 10, 10
size_hint_x: .6
Label:
text: "TEXT"
text_size: self.size
valign: 'middle'
size_hint_x: .2
RightFloatInput:
size_hint_x: .4
text : "100"