【问题标题】:Is there a focus lost event dispatcher for a kivy TextInput?kivy TextInput 是否有焦点丢失事件调度程序?
【发布时间】:2019-06-01 21:29:54
【问题描述】:

问题:

如果multiline = True TextInput 失去焦点,有没有办法触发事件?

背景:

我已经尝试过on_touch_up 功能。但它返回我所有TextInputs 的实例,而不仅仅是当前小部件。我尝试了text_validate_unfocus = False,结果相同。

代码:

import kivy
kivy.require("1.10.1")

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty, NumericProperty
from kivy.uix.textinput import TextInput
from kivy.uix.bubble import Bubble
from kivy.lang import Builder
from kivy.storage.jsonstore import JsonStore

Builder.load_string('''
#: import Window kivy.core.window.Window
<Button>:
    background_normal: ''
<Label>:
    canvas.before:
        Color:
            rgba: (0,0.59,0.36,1)
        Rectangle:
            pos: self.pos
            size: self.size
<TextInput>:
    hint_text: 'Nuwe nota'
    font_size: self.height / 4.5 if self.focus else self.height / 3
    background_normal: ''
    background_active: ''
    foreground_color: (0,0.61,0.36,1) if self.focus else (0.71,0.75,0.71,1)
    unfocus_on_touch: False
    canvas.after:
        Color:
            rgb: (0,0,0,1)
        Line:
            points: self.pos[0] , self.pos[1], self.pos[0] + self.size[0], self.pos[1]
    size_hint_y: None
    height: Window.height / 6 if self.focus else Window.height / 12
<ChoiceBubble>:
    orientation: 'horizontal'
    size_hint: (None, None)
    size: (160, 120)
    pos_hint: {'top': 0.2, 'right': 0.8}
    arrow_pos: 'top_left'
    BubbleButton:
        text: 'Save'
    BubbleButton:
        text: 'Encrypt..'
    BubbleButton:
        text: 'Delete'
        on_release: root.del_txt_input()
<Notation>:
    canvas:
        Color:
            rgba: (0,0.43,0.37,1)
        Rectangle:
            pos: self.pos
            size: self.size
    Label:
        pos_hint: {'top': 1, 'right': 0.8}
        size_hint: [0.8, None]
        height: Window.height / 15
    Button:
        color: (0,0,0,1)
        pos_hint: {'top': 1, 'right': 0.9}
        size_hint: [0.1, None]
        height: Window.height / 15
        Image:
            source: 'gear_2.png'
            center_y: self.parent.center_y
            center_x: self.parent.center_x
            size: self.parent.width /1.5, self.parent.height/ 1.5
            allow_stretch: True
    Button:
        color: (0,0,0,1)
        pos_hint: {'top': 1, 'right': 1}
        size_hint: [0.1, None]
        height: Window.height / 15
        on_release: root.add_input()
        Image:
            source: 'plus_text12354.png'
            center_y: self.parent.center_y
            center_x: self.parent.center_x
            size: self.parent.width /1.5, self.parent.height/ 1.5
            allow_stretch: True
    ScrollView:
        size_hint_y: None
        size: Window.width, Window.height
        pos_hint: {'top': 0.92, 'right': 1}
        GridLayout:
            id: text_holder
            cols: 1
            pos_hint: {'top': 0.92, 'right': 1}
            padding: 4
            size_hint_x: 1
            size_hint_y: None
            height: self.minimum_height

''')
class ChoiceBubble(Bubble):
    pass
class TextInput(TextInput):
    got_txt = ObjectProperty(None)
    def on_touch_up(self, touch):
        if not self.collide_point(*touch.pos):
            self.text_validate_unfocus = False
            note = Notation()
            note.show_bubble
            self.got_txt=note.que_txt_input(self)
        return super(TextInput, self).on_touch_up(touch)
class Notation(FloatLayout):
    which_txt = ObjectProperty(None)
    new_txt = ObjectProperty(None)
    cnt = NumericProperty(0)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.the_file=JsonStore('txt_input.json')
        self.cnt = self.the_file.count()
        lst = self.the_file.keys
    def add_input(self):
        txt_hld = self.ids.text_holder
        self.cnt += 1
        self.new_txt = TextInput(id=str(self.cnt))
        self.the_file.put(str(self.cnt), the_id=str(self.cnt), the_input='')
        txt_hld.add_widget(self.new_txt)
    def que_txt_input(self, instance):
        self.which_txt = instance
        print(instance.text, instance)
        return instance
    def del_txt_input(self):
        print(self.which_txt)
    def the_file(self, notestore):
        self.notestore = notestore
    def show_bubble(self):
        self.add_widget(ChoiceBubble())
    def get_store(self):
        the_keys = list(self.the_file.keys)
        print(the_keys)
        return the_keys

class theNoteApp(App):
    title = 'My Notes'
    def build(self):
        return Notation()

if __name__ == '__main__':
    theNoteApp().run()

期望的结果:

一旦失去焦点,我希望在root class 的顶部添加一个气泡widget。这将使用户可以选择将刚刚失去焦点的TextInput id 和文本保存、加密或删除到JSON 文件中。

【问题讨论】:

    标签: python python-3.x kivy kivy-language


    【解决方案1】:

    问题

    1. 对象的多个实例,Notation。一个来自App 类中的build() 方法(return Notation()),另一个实例在on_touch_up() 方法(note = Notation()) 中创建,只要on_touch_up 事件被触发。在on_touch_up() 方法中创建的那些实例没有可见视图,即它不会显示在窗口中。
    2. AttributeError: 'ChoiceBubble' object has no attribute 'del_txt_input'
    3. ChoiceBubble 中的文本不可见,即默认文本颜色为白底白字。

    解决方案

    1. 使用App.get_running_app().root 获取实例化的根。
    2. root.del_txt_input() 替换为app.root.del_txt_input()
    3. color: 0, 0, 0, 1 添加到类规则,&lt;Label&gt;:
    4. 使用on_focus事件显示BubbleButton

    片段 - kv

    <Label>:
        color: 0, 0, 0, 1
        ...
    
    <ChoiceBubble>:
        ...
        BubbleButton:
            text: 'Delete'
            on_release: app.root.del_txt_input()
    

    片段 - py 文件

    class TextInput(TextInput):
        got_txt = ObjectProperty(None)
    
        def on_focus(self, instance, value):
            if not value:   # defocused
                note = App.get_running_app().root
                note.show_bubble()
                self.got_txt = note.que_txt_input(self)
    

    输出

    【讨论】:

      【解决方案2】:

      on_focus 事件将在焦点布尔值更改时触发。

      我已经尝试过 on_touch_up 功能。但它返回我所有 TextInputs 的实例,而不仅仅是当前小部件。

      这是因为您没有编写任何代码将其限制为您关心的小部件,如果您愿意,可以这样做。

      【讨论】:

        猜你喜欢
        • 2016-01-15
        • 1970-01-01
        • 2018-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-04
        • 2012-03-05
        • 2018-09-12
        相关资源
        最近更新 更多