簡體   English   中英

這是Kivy中的錯誤嗎? DropDown + ScreenManager無法正常工作

[英]Is it a bug in Kivy? DropDown + ScreenManager not working as expected

如果在使用DropDown的屏幕之前存在屏幕,則使用ScreenManager和DropDown會產生可復制的困難。 我已經為此苦苦掙扎了幾天,因為我是一個初學者,所以我認為這是我的錯。
我將代碼分解到問題的核心,因此我的預期功能丟失了。 打算使用一個增量搜索字段,以便下拉列表中僅顯示適當的選項。 這就是為什么我需要將輸入小部件綁定到下拉按鈕的原因。 我有一個解決方案,它在screenmanager中無法正常工作。
請考慮以下代碼:

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)如果是錯誤,應該在哪里宣布它?

3)目前對我來說最重要:現在,用戶必須手動從editfield刪除ComboEdit.text中的給定字符串,以用自己的輸入替換它。 太丑了 您有解決方法的想法嗎? 是否可以選擇虛擬文本,以便如果用戶啟動輸入將立即被覆蓋?

我試圖這樣做

   ComboEdit:
        ...
        focus: True
        select_all: True

但沒有效果?

任何對錯誤的肯定,任何解決的暗示,任何我在這里做錯的解釋都將非常非常受歡迎!

可以用很多(更好的方式)完成,但是可以。

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

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM