当我输入MyFloatInput
TextInput时,文字从TextInput的right
侧开始,它的工作正常
但我从MyFloatInput
设置了.py
TextInput的值,然后从左侧开始。它没有显示在右侧。
有人能告诉我代码有什么问题吗?
import kivy
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.uix.textinput import TextInput
Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (400, 100)
class MyFloatInput(TextInput):
def __init__(self, **kwargs):
super(MyFloatInput, self).__init__(**kwargs)
self.multiline = False
def right_adjust(self, text):
max_width = self.width - self.padding[0] - self.padding[2]
new_text = text
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[0] != ' ':
break
else:
new_text = new_text[1:]
text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
return new_text
def delete_selection(self, from_undo=False):
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(MyFloatInput, self).delete_selection(from_undo=from_undo)
cur_text = self._lines[cr]
super(MyFloatInput, 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'):
cc, cr = self.cursor
initial_len = len(self._lines[cr])
super(MyFloatInput, self).do_backspace(from_undo=from_undo, mode=mode)
cc, cr = self.cursor
cur_text = self._lines[cr]
super(MyFloatInput, 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):
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:
num = float(new_text) # throw exception if new_text is invalid float
except ValueError:
return
self._lines[cr] = ''
super(MyFloatInput, self).insert_text(new_text, from_undo=from_undo)
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):
num = float(text) # throws exception if text is invalid float
self._refresh_text(self.right_adjust(text))
def on_text(self, instance, text):
#num = float(text) # throws exception if text is invalid float
self._refresh_text(self.right_adjust(text))
class Testing(Screen):
def __init__(self, **kwargs):
super(Testing, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: setattr(self.test, 'text', str(100)))
class Test(App):
def build(self):
self.root = Builder.load_file('test.kv')
return self.root
if __name__ == '__main__':
Test().run()
Testing:
test:test
BoxLayout:
orientation: "vertical"
padding : 20, 20
BoxLayout:
orientation: "horizontal"
padding: 10, 10
spacing: 10, 10
size_hint_x: .6
Label:
text: "No."
text_size: self.size
valign: 'middle'
size_hint_x: .2
MyFloatInput:
size_hint_x: .6
id : test
答案 0 :(得分:4)
我不知道如何使用TextInput
的可用选项来做到这一点。但可以通过扩展TextInput
来完成。这是一个MyFloatInput
类:
import string
class MyFloatInput(TextInput):
def __init__(self, **kwargs):
super(MyFloatInput, self).__init__(**kwargs)
self.multiline = False
def insert_text(self, theText, from_undo=False):
if theText not in string.digits and theText != '.':
return
if '.' in self.text and theText == '.':
return
maxWidth = self.width - self.padding[0] - self.padding[2]
cc, cr = self.cursor
curText = self._lines[cr]
new_text = curText[:cc] + theText + curText[cc:]
textWidth = self._get_text_width(new_text, self.tab_width, self._label_cached)
while textWidth < maxWidth:
new_text = ' ' + new_text
textWidth = self._get_text_width(new_text, self.tab_width, self._label_cached)
while textWidth >= maxWidth:
if new_text[0] != ' ':
break
else:
new_text = new_text[1:]
textWidth = self._get_text_width(new_text, self.tab_width, self._label_cached)
self._lines[cr] = ''
self.cursor = (0,cr)
super(MyFloatInput, self).insert_text(new_text, from_undo=from_undo)
这应该做你想做的事情,并进行float
过滤。要使用它,请将其包含在.py文件中,并将.kv文件的TextInput
部分替换为:
MyFloatInput:
size_hint_x: .2
请注意,这仅适用于单行输入,因此__init__
方法会将multiline
设置为False
。此代码使用以_
开头的方法和变量,因此如果TextInput
类更新,代码可能会中断。
答案 1 :(得分:2)
我对MyFloatInput
课程进行了重大修改。它现在不再需要string
导入。它现在处理删除选择,现在您可以使用set_right_adj_text("some text")
方法从.py文件设置文本。这是改进的类:
class MyFloatInput(TextInput):
def __init__(self, **kwargs):
super(MyFloatInput, self).__init__(**kwargs)
self.multiline = False
def right_adjust(self, text):
max_width = self.width - self.padding[0] - self.padding[2]
new_text = text
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[0] != ' ':
break
else:
new_text = new_text[1:]
text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
return new_text
def on_size(self, instance, value):
super(MyFloatInput, 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(MyFloatInput, 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 True
def delete_selection(self, from_undo=False):
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(MyFloatInput, self).delete_selection(from_undo=from_undo)
cur_text = self._lines[cr]
super(MyFloatInput, 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'):
cc, cr = self.cursor
initial_len = len(self._lines[cr])
super(MyFloatInput, self).do_backspace(from_undo=from_undo, mode=mode)
cc, cr = self.cursor
cur_text = self._lines[cr]
super(MyFloatInput, 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):
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:
num = float(new_text) # throw exception if new_text is invalid float
except ValueError:
return
self._lines[cr] = ''
super(MyFloatInput, self).insert_text(new_text, from_undo=from_undo)
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):
num = float(text) # throws exception if text is invalid float
self._refresh_text(self.right_adjust(text))