是基维的虫子吗?DropDown+屏幕管理器未按预期工作

2024-05-15 03:33:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有复制困难使用屏幕管理器和下拉菜单,如果有屏幕前的下拉菜单。 我已经为此挣扎了好几天了,因为我是个初学者,我认为这是我的错。
我将代码简化为问题的核心,这样我的预期功能就丢失了。预期是一个增量搜索字段,这样只有适当的选项才会显示在下拉列表中。这就是为什么我需要一个绑定到下拉按钮的输入小部件。我有一个解决方案,就是与屏幕管理器的工作不一样。
请考虑以下代码:

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()

我偶然发现:我需要为组合编辑.text,如果没有-将其作为注释或分配“”-我将得到此回溯:

^{pr2}$

我的问题是:

1)可能是bug还是我做错了什么?在

2)如果是一个bug,那么在哪里宣布它是正确的?在

3)现在对我来说最重要的是:现在用户必须删除组合编辑.text从editfield手动替换为他自己的输入。这太难看了。你有什么解决办法吗?是否可以选择虚拟文本,以便在用户启动输入时立即覆盖它?在

我试着这样做

   ComboEdit:
        ...
        focus: True
        select_all: True

但没有效果?在

任何关于这个错误的认识,任何绕过它的提示,任何关于我在这里做错了什么的解释都是非常欢迎的!在


Tags: instancetextfromimportselfsizeondef
1条回答
网友
1楼 · 发布于 2024-05-15 03:33:31

可以做很多(更好的?)是的,但这很管用。在

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: "working?"
            font_size: '20px'
        ComboEdit:
            size_hint: .5, .5
            pos_hint: {'center':(.5, .5)}
            font_size: '100px'
            multiline: False
''')

class ComboEdit(TextInput):
    options = ListProperty([])

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

    def on_options(self, instance, value):

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

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

    def on_text(self, instance, value):

        self.options = [str(i) for i in range(0,8)]
        if not self.get_root_window():
            return # do proceed if I'm not displayed <=> If have no parent
        self.ddn.open(self)


class ComboLayout(BoxLayout):
    pass

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()

希望有帮助。在

相关问题 更多 >

    热门问题