这是Kivy的一个错误吗? DropDown + ScreenManager无法按预期工作

时间:2015-12-02 13:43:27

标签: python kivy

如果在使用DropDown的屏幕之前有屏幕,我使用ScreenManager和DropDown会出现可重现的问题。 我现在已经挣扎了几天,因为我是初学者,我认为这是我的错 我将代码融化到问题的核心,这样我的预期功能就会丢失。预期的是增量搜索字段,以便在下拉列表中仅显示适当的选项。这就是为什么我需要一个绑定到下拉按钮的输入小部件。我有一个解决方案,它只是没有像屏幕管理员那样按预期工作 请考虑以下代码:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.properties import ListProperty, StringProperty
import re
from kivy.lang import Builder

Builder.load_string('''
<Intro>:
    BoxLayout:
        Button:
            text: 'Press to go to SecondScreen'
            font_size: '20px'
            on_release: root.manager.current = 'SecondScreen'
<SecondScreen>:
    ComboLayout:
        Label:
            text: "Dropdown on SecondScreen \\n\\n if ComboEdit.text doesn't have \\n a non-empty string assigned \\n code is broken!"
            font_size: '20px'
        ComboEdit:
            size_hint: .5, .5
            pos_hint: {'center':(.5, .5)}
            on_text: self.parent.on_text(self, args[1])
            text: 'X'                 ## <<<=== THIS IS NECESSARY, REALLY!?!
            font_size: '100px'
            multiline: False
''')

class ComboEdit(TextInput):
    options = ListProperty(('',))

    def __init__(self, **kw):
        ddn = self.drop_down = DropDown()
        ddn.bind(on_select=self.on_select)
        super(ComboEdit, self).__init__(**kw)

    def on_options(self, instance, value):
        ddn = self.drop_down
        ddn.clear_widgets()
        for option in value:
            but = Button(text=option,
                         size_hint_y=None,
                         height='36sp',
                         on_release=lambda btn: ddn.select(btn.text))
            ddn.add_widget(but)

    def on_select(self, instance, value):
        self.text = value

class ComboLayout(BoxLayout):
    def on_text(self, instance, value):
        instance.options = [str(i) for i in range(0,8)]
        instance.drop_down.open(instance)

class Intro(Screen):
    pass
class SecondScreen(Screen):
    pass

class BugDemoApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(Intro(name='Intro'))
        sm.add_widget(SecondScreen(name='SecondScreen'))
        return sm

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

偶然我发现:我需要为ComboEdit.text指定一些非空字符串,如果没有 - 将其作为注释或指定“” - 我得到这个追溯:

   File "C:/Users/ORANG/PycharmProjects/waldi/playground/widgets.py", line 56, in on_text
     instance.drop_down.open(instance)
   File "C:\Kivy-1.9.0-py2.7-win32-x64\kivy27\kivy\uix\dropdown.py", line 215, in open
     'Cannot open a dropdown list on a hidden widget')
 kivy.uix.dropdown.DropDownException: Cannot open a dropdown list on a hidden widget

我的问题是:

1)这可能是一个错误,还是我在这里做错了什么?

2)如果它是一个错误,哪里是宣布它的正确位置?

实际上对我来说最重要的那一刻:现在用户必须手动从编辑字段中删除ComboEdit.text中的给定字符串,以用他自己的输入替换它。这太丑了。你对解决方法有什么想法吗?是否可以选择虚拟文本,以便如果用户启动输入,它将立即被覆盖?

我试着这样做

   ComboEdit:
        ...
        focus: True
        select_all: True

但没有效果?

任何对这个错误的承认,任何解决它的提示,任何解释我在这里做错了都会非常受欢迎!

1 个答案:

答案 0 :(得分:2)

可以通过多种(更好的?)方式完成,但这样做有效。

@SuppressWarnings("unchecked")
@Override
@Transactional
public List<FormFields> findFormFieldsByFormFieldIds(
        List<Integer> formFiledsIds) {
    try {
        logger.info("############### findFormFieldsByFormFieldIds dao called ################");
        System.out.println("############### getDashboardXFieldByDashboardIds size : "+formFiledsIds.size());
        Session session=sessionFactory.getCurrentSession();
        Criteria criteria=session.createCriteria(FormFields.class);
        criteria.add(Restrictions.in("fieldId", formFiledsIds)).addOrder(Order.asc("sequenceNo"));
        List<FormFields> list = criteria.list();
        logger.info("############### getDashboardXFieldByDashboardIds size : "+list.size());
        System.out.println("############### getDashboardXFieldByDashboardIds size : "+list.size());
        return list;
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
    return null;
}

希望它有所帮助。