ReferenceError: объект со слабой ссылкой больше не существует Kivy DropDown

Запуск этого примера DropDown работает. Однако после некоторого использования / времени я получаю сообщение об ошибке ReferenceError: объект со слабой ссылкой больше не существует

Вероятно, это связано с проблемой в on_release: dropdown.open (self)

Бонус за то, почему on_parent: self.dismiss () также не работает с тем, как я настроил эти виджеты. Без этого у меня есть элементы подменю, появляющиеся при первом запуске приложения, и если это включено, элементы подменю мигают (появляются и быстро исчезают).

#!/usr/bin/kivy
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty
from kivy.uix.dropdown import DropDown
from kivy.core.window import Window

Window.size = (400, 240)

sm = """

ScreenManager:
    id:manager
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 0.5
        Rectangle:
            pos: 0,0
            size: 800, 480
    Notes:
        id:Notes
        name: 'Notes'
        manager: manager

<Notes>:
    name: "Notes"
    orientation: "vertical"

    FloatLayout:
        size_hint: None, None

        canvas.before:
            Color:
                rgba: 1, 1, 0, 1    

        Button:

            id: mainbutton
            text: "Menu name"
            font_size: 20
            size_hint: None, None
            size: 150, 50
            pos: 20,400
            on_release:dropdown.open(self)

        CustomDropDown:
            id: dropdown
            #on_parent: self.dismiss()
            on_select: mainbutton.text = '{}'.format(args[1])

            Button:
                id: button1
                text: 'First Item'
                size_hint_y: None
                height: 40
                font_size: 18
                on_release: dropdown.select('First Item')

            Button:
                id: button2
                text: 'Second Item'
                size_hint_y: None
                height: 40
                font_size: 18
                on_release: dropdown.select('Second Item')

            Button:
                id: button3
                text: 'Third Item'
                size_hint_y: None
                height: 40
                font_size: 18
                on_release: dropdown.select('Third Item')

"""


class Notes(Screen):
    pass

class CustomDropDown(DropDown):
    pass

#dropdown = CustomDropDown()


class TestApp(App):

    def build(self):

        return Builder.load_string(sm)

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

person fastmhc    schedule 05.09.2017    source источник


Ответы (2)


В дочернем виджете CustomDropDown

С on_parent: self.dismiss ()

При нажатии на основную кнопку Название меню иногда появляется ошибка ReferenceError: объект со слабой ссылкой больше не существует. Если ReferenceError отсутствует, раскрывающийся список мигает (появляется и быстро исчезает). Причина в том, что DropDown был закрыт.

Без on_parent: self.dismiss ()

Он отобразит список CustomDropDown при запуске приложения. При нажатии главной кнопки Название меню раскрывающийся список, который появлялся при запуске, исчезает, но в нем отображается раскрывающийся список вдвое большей длины, т.е. элементы подменю повторяются дважды.

Примечание

Выпадающий список похож на Popup. Это особый виджет. Не пытайтесь добавить его как дочерний элемент к любому другому виджету. Если вы это сделаете, они будут обрабатываться как обычный виджет и не будут скрыты в фоновом режиме.

См. Пример ниже, иллюстрирующий, как создать раскрывающийся список.

Пример

main.py

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.core.window import Window


Window.size = (800, 480)


class CustomDropDown(DropDown):
    pass


class Notes(Screen):
    pass


class MyScreenManager(ScreenManager):
    pass


class TestApp(App):
    title = "Kivy Drop-Down List Demo"

    def build(self):
        return MyScreenManager()


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

test.kv

#:kivy 1.10.0
#:import Factory kivy.factory.Factory

<CustomDropDown>:
    on_select: app.root.ids.Notes.ids.mainbutton.text = '{}'.format(args[1])

    Button:
        id: button1
        text: 'First Item'
        size_hint_y: None
        height: 40
        font_size: 18
        on_release: root.select(self.text)

    Button:
        id: button2
        text: 'Second Item'
        size_hint_y: None
        height: 40
        font_size: 18
        on_release: root.select(self.text)

    Button:
        id: button3
        text: 'Third Item'
        size_hint_y: None
        height: 40
        font_size: 18
        on_release: root.select(self.text)

<MyScreenManager>:
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 0.5
        Rectangle:
            pos: 0,0
            size: 800, 480
    Notes:
        id:Notes
        name: 'Notes'

<Notes>:
    orientation: "vertical"

    FloatLayout:
        size_hint: None, None

        canvas.before:
            Color:
                rgba: 1, 1, 0, 1

        Button:
            id: mainbutton
            text: "Menu name"
            font_size: 20
            size_hint: None, None
            size: 150, 50
            pos: 20,400
            on_release: Factory.CustomDropDown().open(self)

Выход

Запуск приложения

person ikolim    schedule 12.09.2017

из: $ Yourkivydir / kivy-examples / demo / showcase / data / screen

ShowcaseScreen:
    fullscreen: True
    name: 'DropDown'

    # trick to not lost the Dropdown instance
    # Dropdown itself is not really made to be used in kv.
    __safe_id: [dropdown.__self__]

    Button:
        id: btn
        text: '-'
        on_release: dropdown.open(self)
        size_hint_y: None
        height: '48dp'

    Widget:
        on_parent: dropdown.dismiss()

    DropDown:

        id: dropdown
        on_select: btn.text = 'Selected value: {}'.format(args[1])

        Button:
            text: 'Value A'
            size_hint_y: None
            height: '48dp'
            on_release: dropdown.select('A')

        Button:
            text: 'Value B'
            size_hint_y: None
            height: '48dp'
            on_release: dropdown.select('B')

        Button:
            text: 'Value C'
            size_hint_y: None
            height: '48dp'
            on_release: dropdown.select('C')
person Ron87k    schedule 26.03.2018
comment
Этот ответ будет более полезен для будущих пользователей (и, вероятно, принесет вам больше голосов), если вы включите краткое объяснение того, что делает ваш код и как он решает проблему. - person divibisan; 26.03.2018
comment
Как отметил divibisan, не сразу очевидно, что делать, поэтому позвольте мне пояснить, что сработало для меня, основываясь на этом ответе. В верхней части файла kv, предоставленного Ron87k, есть комментарии. В файле kv присвойте своему DropDown идентификатор, а затем в объекте / виджете, под которым появляется DropDown, добавьте __safe_id: [dropdown .__ self]. - person PlexLuthor; 18.01.2021