在不是焦点时存储 TextInput 的选择(Kivy)
Storing selection of TextInput when not is focus (Kivy)
我有一个 TextInput 和一个按钮,我的目标是能够 select 来自 TextInput 的一些文本,然后按下一个调用打印函数的按钮:selection_text、selection_to 和 selection_from。
但是,因为在按下按钮时 TextInput 不在焦点上,所以 selection 丢失并且函数 returns 没有 AND/OR 不正确的值。
我在类似的问题中看到过这行代码,但我无法通过弄乱代码或查看 TextInput 文档来弄清楚它的意思,因为我只看到它叫做来自 'on_focus' 函数
Clock.schedule_once(lambda dt: new_post_input.selection_text)
我还不能在示例程序中重现该问题,因为当我将小部件放入它们自己的程序时它起作用了
main.py
from kivy.app import App
from kivy.properties import BooleanProperty, StringProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.modules import inspector
from kivy.core.window import Window
class NewPost(FloatLayout):
buttons_disabled = BooleanProperty(False)
cancle_button_disabled = BooleanProperty(True)
preview_text = StringProperty()
def make_bold(self, new_post_input, selected):
print('Selected = ' + selected)
print('Button has been pushed')
def preview_post(self, Button, cancleButton, TextInput, Label):
#self.preview_text = ('Hello\n' + TextInput.text)
self.buttons_disabled = True
self.cancle_button_disabled = False
Label.opacity = 1
Label.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
TextInput.opacity = 0
cancleButton.opacity = 1
cancleButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
#print(TextInput.text)
def back_from_preview(self, Button, previewButton, TextInput, Label):
self.buttons_disable = False
self.cancle_button_disabled = True
Label.opacity = 0
Label.pos_hint = {'center_x': 0.5, 'center_y': -1}
TextInput.opacity = 1
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
previewButton.opacity = 1
previewButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
class SelectionApp(App):
def build(self):
inspector.create_inspector(Window, SelectionApp)
SelectionApp().run()
selection.kv
PageLayout:
Label:
text: 'Swipe to the next page'
font_size: dp(50)
Label:
text: 'And again'
canvas.before:
Color:
rgba: (0,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
NewPost:
id: new_post
canvas.after:
Color:
rgba: 0,1,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
id: main_new_post
orientation: 'vertical'
padding: '10dp', '16dp'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
AnchorLayout:
size_hint: 1, .05
anchor_x: 'right'
anchor_y: 'center'
Label:
text: 'New Post'
size_hint: None, None
size: '100dp', '30dp'
color: .8, 0, 0, 1
font_size: '16dp'
#pos_hint: {'center_x': 0.8, 'center_y': 0.5}
Label:
size_hint: 1, .035
text: ''
font_size: '1dp'
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .38
FloatLayout:
TextInput:
id: new_post_input
#disabled: new_post.buttons_disabled
opacity: 1
background_color: 0, 0, 0, 1
foreground_color: 1, 1, 1, 1
background_disable_normal: True
multiline: True
font_size: '15dp'
padding: '10dp', '10dp'
selection_color: (.8, 0, 0, .5)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
allow_copy: True
#on_focus: new_post.on_focus(self)
canvas.after:
Color:
rgba: 1,1,1,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
orientation: 'vertical'
id: preview_new_post_label
opacity: 0
pos_hint: {'center_x': 0.5, 'center_y': -1}
canvas.before:
Color:
rgba: (.8,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
canvas:
Color:
rgba:0.8,0,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(5))
ScrollView:
always_overscroll: False
bar_color: (0,0,0,0)
Label:
text: ('Someone:\n' + new_post_input.text)
padding: "10dp", "12dp"
size_hint: None, None
height: self.texture_size[1]
width: self.parent.width
font_size: "12dp"
text_size: self.width, None
color: 0,0,0,1
multiline: True
markup: True
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Text Modification'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selection_text)
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
#padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Post Category'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
ToggleButton:
text: "Opinion"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.update_catagory(self, 'opinions')
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
演示程序运行:YouTube link
感谢任何 suggestions/solutions :)
更新
事实证明,当 TextInput 位于超过 2 页的 PageLayout 中时,selection 似乎停止工作(在我的程序中)。
我创建了一个粗略的演示程序来展示问题并将其放入 .py 和 .kv
您可以通过创建自定义 TextInput
实例并覆盖其方法之一来实现。
class MyTextInput(TextInput):
selected_text = StringProperty("")
# Use this prop. instead of 'selection_text'.
def cancel_selection(self):
self.selected_text = self.selection_text
super().cancel_selection()
现在在任何需要的地方使用这个实例和新的 属性。
在.kv
,
FloatLayout:
MyTextInput:
id: new_post_input
.
.
.
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selected_text)
我有一个 TextInput 和一个按钮,我的目标是能够 select 来自 TextInput 的一些文本,然后按下一个调用打印函数的按钮:selection_text、selection_to 和 selection_from。
但是,因为在按下按钮时 TextInput 不在焦点上,所以 selection 丢失并且函数 returns 没有 AND/OR 不正确的值。
我在类似的问题中看到过这行代码,但我无法通过弄乱代码或查看 TextInput 文档来弄清楚它的意思,因为我只看到它叫做来自 'on_focus' 函数
Clock.schedule_once(lambda dt: new_post_input.selection_text)
我还不能在示例程序中重现该问题,因为当我将小部件放入它们自己的程序时它起作用了
main.py
from kivy.app import App
from kivy.properties import BooleanProperty, StringProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.modules import inspector
from kivy.core.window import Window
class NewPost(FloatLayout):
buttons_disabled = BooleanProperty(False)
cancle_button_disabled = BooleanProperty(True)
preview_text = StringProperty()
def make_bold(self, new_post_input, selected):
print('Selected = ' + selected)
print('Button has been pushed')
def preview_post(self, Button, cancleButton, TextInput, Label):
#self.preview_text = ('Hello\n' + TextInput.text)
self.buttons_disabled = True
self.cancle_button_disabled = False
Label.opacity = 1
Label.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
TextInput.opacity = 0
cancleButton.opacity = 1
cancleButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
#print(TextInput.text)
def back_from_preview(self, Button, previewButton, TextInput, Label):
self.buttons_disable = False
self.cancle_button_disabled = True
Label.opacity = 0
Label.pos_hint = {'center_x': 0.5, 'center_y': -1}
TextInput.opacity = 1
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
previewButton.opacity = 1
previewButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
class SelectionApp(App):
def build(self):
inspector.create_inspector(Window, SelectionApp)
SelectionApp().run()
selection.kv
PageLayout:
Label:
text: 'Swipe to the next page'
font_size: dp(50)
Label:
text: 'And again'
canvas.before:
Color:
rgba: (0,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
NewPost:
id: new_post
canvas.after:
Color:
rgba: 0,1,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
id: main_new_post
orientation: 'vertical'
padding: '10dp', '16dp'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
AnchorLayout:
size_hint: 1, .05
anchor_x: 'right'
anchor_y: 'center'
Label:
text: 'New Post'
size_hint: None, None
size: '100dp', '30dp'
color: .8, 0, 0, 1
font_size: '16dp'
#pos_hint: {'center_x': 0.8, 'center_y': 0.5}
Label:
size_hint: 1, .035
text: ''
font_size: '1dp'
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .38
FloatLayout:
TextInput:
id: new_post_input
#disabled: new_post.buttons_disabled
opacity: 1
background_color: 0, 0, 0, 1
foreground_color: 1, 1, 1, 1
background_disable_normal: True
multiline: True
font_size: '15dp'
padding: '10dp', '10dp'
selection_color: (.8, 0, 0, .5)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
allow_copy: True
#on_focus: new_post.on_focus(self)
canvas.after:
Color:
rgba: 1,1,1,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
orientation: 'vertical'
id: preview_new_post_label
opacity: 0
pos_hint: {'center_x': 0.5, 'center_y': -1}
canvas.before:
Color:
rgba: (.8,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
canvas:
Color:
rgba:0.8,0,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(5))
ScrollView:
always_overscroll: False
bar_color: (0,0,0,0)
Label:
text: ('Someone:\n' + new_post_input.text)
padding: "10dp", "12dp"
size_hint: None, None
height: self.texture_size[1]
width: self.parent.width
font_size: "12dp"
text_size: self.width, None
color: 0,0,0,1
multiline: True
markup: True
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Text Modification'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selection_text)
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
#padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Post Category'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
ToggleButton:
text: "Opinion"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.update_catagory(self, 'opinions')
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
演示程序运行:YouTube link
感谢任何 suggestions/solutions :)
更新
事实证明,当 TextInput 位于超过 2 页的 PageLayout 中时,selection 似乎停止工作(在我的程序中)。
我创建了一个粗略的演示程序来展示问题并将其放入 .py 和 .kv
您可以通过创建自定义 TextInput
实例并覆盖其方法之一来实现。
class MyTextInput(TextInput):
selected_text = StringProperty("")
# Use this prop. instead of 'selection_text'.
def cancel_selection(self):
self.selected_text = self.selection_text
super().cancel_selection()
现在在任何需要的地方使用这个实例和新的 属性。
在.kv
,
FloatLayout:
MyTextInput:
id: new_post_input
.
.
.
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selected_text)