zoukankan      html  css  js  c++  java
  • Kivy TextInput IndexError: list index out of range

    使用场景

    在一个触摸屏POS中使用一个Kivy 的TextInput控件做商品扫码输入, 要求把输入框隐藏了

    环境

    Python: 3.6.2
    Kivy: 1.11.1
    OS:Windows10
    

    代码

    <FunButtonScreen>:
        BoxLayout:
            size_hint:1,1
            orientation:'vertical'
            TextInput:
                id: id_scan_plu
                size_hint: None, None
                height: 0
                 0
                cursor_ 0
                # multiline: False
            FunButtonBox:
                size_hint: 1, 1
                id: button_box
    

    以上代码通过heightwidthid为id_scan_plu的TextInput控件隐藏了, 效果图如下红框处实际上有一个TextInput输入框

    效果图

    问题

    POS是使用的触摸屏大部分是正常的,偶尔已报IndexError: list index out of range异常, 而KeyEvent只有扫码枪, 为什么会报key_down异常呢?

    2020-02-17 19:14:09,114 MainThread INFO : Base: Leaving application in progress...
    2020-02-17 19:14:09,115 MainThread WARNING : stderr: Traceback (most recent call last):
    2020-02-17 19:14:09,115 MainThread WARNING : stderr:   File "pos_main.py", line 90, in <module>
    2020-02-17 19:14:09,116 MainThread WARNING : stderr:     main()
    2020-02-17 19:14:09,117 MainThread WARNING : stderr:   File "pos_main.py", line 77, in main
    2020-02-17 19:14:09,117 MainThread WARNING : stderr:     MainWindow().run()
    2020-02-17 19:14:09,118 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivyapp.py", line 828, in run
    2020-02-17 19:14:09,121 MainThread WARNING : stderr:     runTouchApp()
    2020-02-17 19:14:09,122 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivyase.py", line 504, in runTouchApp
    2020-02-17 19:14:09,124 MainThread WARNING : stderr:     EventLoop.window.mainloop()
    2020-02-17 19:14:09,124 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivycorewindowwindow_sdl2.py", line 663, in mainloop
    2020-02-17 19:14:09,126 MainThread WARNING : stderr:     self._mainloop()
    2020-02-17 19:14:09,127 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivycorewindowwindow_sdl2.py", line 602, in _mainloop
    2020-02-17 19:14:09,128 MainThread WARNING : stderr:     self.modifiers):
    2020-02-17 19:14:09,129 MainThread WARNING : stderr:   File "kivy\_event.pyx", line 714, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8146)
    2020-02-17 19:14:09,130 MainThread WARNING : stderr:   File "kivy\_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy\_event.c:14035)
    2020-02-17 19:14:09,132 MainThread WARNING : stderr:   File "kivy\_event.pyx", line 1149, in kivy._event.EventObservers._dispatch (kivy\_event.c:13564)
    2020-02-17 19:14:09,133 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivycorewindow\__init__.py", line 159, in _on_window_key_down
    2020-02-17 19:14:09,135 MainThread WARNING : stderr:     return self.dispatch('on_key_down', keycode, text, modifiers)
    2020-02-17 19:14:09,136 MainThread WARNING : stderr:   File "kivy\_event.pyx", line 714, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8146)
    2020-02-17 19:14:09,137 MainThread WARNING : stderr:   File "kivy\_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy\_event.c:14035)
    2020-02-17 19:14:09,139 MainThread WARNING : stderr:   File "kivy\_event.pyx", line 1149, in kivy._event.EventObservers._dispatch (kivy\_event.c:13564)
    2020-02-17 19:14:09,140 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivyuix	extinput.py", line 2438, in keyboard_on_key_down
    2020-02-17 19:14:09,145 MainThread WARNING : stderr:     self._key_down(key)
    2020-02-17 19:14:09,145 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivyuix	extinput.py", line 2279, in _key_down
    2020-02-17 19:14:09,149 MainThread WARNING : stderr:     self._alt_l or self._alt_r)
    2020-02-17 19:14:09,149 MainThread WARNING : stderr:   File "d:Python35libsite-packageskivyuix	extinput.py", line 1162, in do_cursor_movement
    2020-02-17 19:14:09,151 MainThread WARNING : stderr:     col = min(len(self._lines[row]), col)
    2020-02-17 19:14:09,152 MainThread WARNING : stderr: IndexError: list index out of range
    

    这个问题在百度、bing、github、SO都没有搜到解决办法,只好阅读源码Python35libsite-packageskivyuix extinput.py

    def do_cursor_movement(self, action, control=False, alt=False):
            '''Move the cursor relative to its current position.
            Action can be one of :
    
                - cursor_left: move the cursor to the left
                - cursor_right: move the cursor to the right
                - cursor_up: move the cursor on the previous line
                - cursor_down: move the cursor on the next line
                - cursor_home: move the cursor at the start of the current line
                - cursor_end: move the cursor at the end of current line
                - cursor_pgup: move one "page" before
                - cursor_pgdown: move one "page" after
    
            In addition, the behavior of certain actions can be modified:
    
                - control + cursor_left: move the cursor one word to the left
                - control + cursor_right: move the cursor one word to the right
                - control + cursor_up: scroll up one line
                - control + cursor_down: scroll down one line
                - control + cursor_home: go to beginning of text
                - control + cursor_end: go to end of text
                - alt + cursor_up: shift line(s) up
                - alt + cursor_down: shift line(s) down
    
            .. versionchanged:: 1.9.1
    
            '''
            if not self._lines:
                return
            pgmove_speed = int(self.height /
                (self.line_height + self.line_spacing) - 1)
            col, row = self.cursor
            if action == 'cursor_up':
                if self.multiline and control:
                    self.scroll_y = max(0, self.scroll_y - self.line_height)
                elif not self.readonly and self.multiline and alt:
                    self._shift_lines(-1)
                    return
                else:
                    row = max(row - 1, 0)
                    col = min(len(self._lines[row]), col)
            elif action == 'cursor_down':
                if self.multiline and control:
                    maxy = self.minimum_height - self.height
                    self.scroll_y = max(0, min(maxy,
                                               self.scroll_y + self.line_height))
                elif not self.readonly and self.multiline and alt:
                    self._shift_lines(1)
                    return
                else:
                    row = min(row + 1, len(self._lines) - 1)
                    col = min(len(self._lines[row]), col)
            elif action == 'cursor_home':
                col = 0
                if control:
                    row = 0
            elif action == 'cursor_end':
                if control:
                    row = len(self._lines) - 1
                col = len(self._lines[row])
            elif action == 'cursor_pgup':
                row = max(0, row - pgmove_speed)
                col = min(len(self._lines[row]), col)
            elif action == 'cursor_pgdown':
                row = min(row + pgmove_speed, len(self._lines) - 1)
                col = min(len(self._lines[row]), col)
            elif (self._selection and self._selection_finished and
                    self._selection_from < self._selection_to and
                    action == 'cursor_left'):
                current_selection_to = self._selection_to
                while self._selection_from != current_selection_to:
                    current_selection_to -= 1
                    if col:
                        col -= 1
                    else:
                        row -= 1
                        col = len(self._lines[row])
            elif (self._selection and self._selection_finished and
                    self._selection_from > self._selection_to and
                    action == 'cursor_right'):
                current_selection_to = self._selection_to
                while self._selection_from != current_selection_to:
                    current_selection_to += 1
                    if len(self._lines[row]) > col:
                        col += 1
                    else:
                        row += 1
                        col = 0
    
            elif action == 'cursor_left':
                if not self.password and control:
                    col, row = self._move_cursor_word_left()
                else:
                    if col == 0:
                        if row:
                            row -= 1
                            col = len(self._lines[row])
                    else:
                        col, row = col - 1, row
            elif action == 'cursor_right':
                if not self.password and control:
                    col, row = self._move_cursor_word_right()
                else:
                    if col == len(self._lines[row]):
                        if row < len(self._lines) - 1:
                            col = 0
                            row += 1
                    else:
                        col, row = col + 1, row
    
            dont_move_cursor = control and action in ['cursor_up', 'cursor_down']
            if dont_move_cursor:
                self._trigger_update_graphics()
            else:
                self.cursor = (col, row)
    

    原来店里配置了外置键盘,当输入Pgup、PgDn键是会引发异常, 由于通过height和width 都是0所以没法上下滚动而异常

    解决办法

    通过透明属性隐藏控件, 即把颜色的rgba都是设置成0, 背景设置为空

    <FunButtonScreen>:
        BoxLayout:
            size_hint:1,1
            orientation:'vertical'
            TextInput:
                id: id_scan_plu
                size_hint: None, None
                height: 40
                 120
                cursor_ 0
                multiline: False
                color: 0, 0, 0, 0
                background_normal: ""
                background_active: ""
                cursor_color: 0, 0, 0, 0
                background_color: 0, 0, 0, 0
                foreground_color: 0, 0, 0, 0
                
            FunButtonBox:
                size_hint: 1, 1
                id: button_box
    
  • 相关阅读:
    STL: merge
    STL: rotate
    javascript的prototype继承问题
    日期正则表达式
    有关linq的一系列学习的文章,值得收藏
    EF读取关联数据
    jQuery UI中的日期选择插件Datepicker
    LINQ的基本语法中八个关键字用法说明
    Shell变量内容的删除、替代与替换
    Shell命令别名与历史命令
  • 原文地址:https://www.cnblogs.com/onsunsl/p/Kivy_TextInput_IndexError.html
Copyright © 2011-2022 走看看