向DropDown添加可变数量的控件-弱引用对象不再存在 [英] Adding variable number of controls to DropDown - weakly-referenced object no longer exists

查看:61
本文介绍了向DropDown添加可变数量的控件-弱引用对象不再存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个下拉列表,其中列出了月份.选择月份"后,我正在尝试在第二个下拉菜单中以正确的天数动态填充按钮.当我这样做时,我得到:

I have a dropdown with a list of the months in it. When the Month is selected, I'm trying to dynamically populate buttons in a second dropdown with the correct number of days. When I do so, I get:

ReferenceError: weakly-referenced object no longer exists

以下是我的文件供参考:

Here are my files for reference:

main.py:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

globIDs = {}

class appScreen(BoxLayout):

    def dayDropPop(self, num):
        globIDs['dayDropDown'].populate(num)


class ExtDropDown(BoxLayout):
    heldValue = ''

    def setID(self, key):
        globIDs[key] = self

    def changeValue(self, sentText, parent):
        self.heldValue = sentText
        parent.text = sentText

class PriorityDropDown(ExtDropDown):
    pass

class MonthDropDown(ExtDropDown):

    def __init__(self, **kwargs):
        super(MonthDropDown, self).__init__(**kwargs)
        self.setID('monthDropDown')

    def monthSelect(self, month):
        monthDay = {'Jan': 31, 'Feb': 29, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30,
                    'Oct': 31, 'Nov': 30, 'Dec': 31}

        numOfDays = monthDay[month]
        appScreen().dayDropPop(numOfDays)

    def testingFurther(self):
        print()

class DayDropDown(ExtDropDown):

    def __init__(self, **kwargs):
        super(DayDropDown, self).__init__(**kwargs)
        self.setID('dayDropDown')

    def populate(self, num):

        for i in range(0, num):
            newButt = Button(text=str(num + 1))
            self.ids.drop.add_widget(newButt)

class schedulerApp(App):

    def build(self):
        return appScreen()

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

scheduler.kv:

scheduler.kv:

<PriorityDropDown>:
    Button:
        id: ddRoot
        text: 'Priority'
        on_release: drop.open(ddRoot)
        size_hint_y: None
        height: root.height

    DropDown:
        id: drop
        on_parent: self.dismiss()
        on_select: root.changeValue(args[1], ddRoot)

        Button:
            text: 'Top'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'High'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Medium'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Low'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)

<MonthDropDown>:
    Button:
        id: ddRoot
        text: 'Month'
        on_release: drop.open(ddRoot)
        size_hint_y: None
        height: root.height

    DropDown:
        id: drop
        on_parent: self.dismiss()
        on_select: root.monthSelect(args[1])

        Button:
            text: 'Jan'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Feb'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Mar'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Apr'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'May'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Jun'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Jul'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Aug'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Sep'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Oct'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Nov'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)
        Button:
            text: 'Dec'
            size_hint_y: None
            height: root.height
            on_release: drop.select(self.text)

<DayDropDown>:
    height: root.height
    Button:
        id: ddRoot
        text: 'Day'
        on_release: drop.open(ddRoot)
        size_hint_y: None
        height: root.height

    DropDown:
        id: drop
        on_parent: self.dismiss()
        on_select: root.changeValue(args[1], ddRoot)

<appScreen>:
    orientation: 'vertical'
    Label:
        size_hint_y: .1
        text: 'Hello World'
    GridLayout:
        size_hint_y:.1
        width: root.width
        cols: 3
        Button:
        Button:
        Button:
    ScrollView:
        canvas.before:
            Color:
                rgba: .3, .3, .3, 5
            Rectangle:
                pos: self.pos
                size: self.size
        GridLayout:
            cols: 3
            Label:
                id: textReceiver
                text: 'Words'
                text_size: self.size
                halign: 'left'
                valign: 'top'
            Label:
            Label:
    BoxLayout:
        size_hint_y: .125
        TextInput:
            size_hint_x: .7
        PriorityDropDown:
            size_hint_x: .3
    BoxLayout:
        size_hint_y: .125
        MonthDropDown:
            size_hint_x: .35
        DayDropDown:
            id: 'dayDrop'
            size_hint_y: 1
            size_hint_x: .2
        TextInput:
            size_hint_x: .45

我认为问题出在有问题的控件是用Kivy代码而不是Python创建的.我所做的测试使我相信我错误地引用了DayDropDown小部件.但是,我不知道该怎么办.考虑到这一点,我将如何使用已有的资源引用DayDropDown?如果那不是我的问题,那么还有什么可能导致引发ReferenceError?

I think the issue stems from the controls in question being created in Kivy code, rather than in Python. What testing I've done leads me to believe that I'm referencing my DayDropDown widget incorrectly. However, I don't know how else I would do so. With that in mind, how would I go about referencing my DayDropDown using what I already have? If that isn't my issue, what else might be causing the ReferenceError to be thrown?

我的代码有点不足.我用方法"getID"(一个简单的返回自我)创建了一个新类"globAddable",然后在其中放置了setID.然后设置我的setID,现在将self.getID()分配给一个变量,然后将该变量用作要添加到globObjects(以前称为globIDs)字典的对象.

Messed with my code a little bit. I created a new class "globAddable" with methods "getID" - a simple return self - and put setID in there instead. I then set my setID now assigns self.getID() to a variable, then uses that variable as the object to be added to the globObjects (formerly globIDs) dictionary.

我还为DropDown对象创建了一个名为ExtDropArray的新类,该类位于DayDropDown中.我将populate()方法移到了这个新类上,以便可以直接由Dropdown而不是其父BoxLayout调用它.我使ExtDropArray和ExtDropDown从globAddable继承来公开setID(和隐式getID)方法.

I also created a new class for my DropDown object, called ExtDropArray, which lives in my DayDropDown. I moved the populate() method to this new class so that it can be called directly by the Dropdown, rather than its parent BoxLayout. I made the ExtDropArray and ExtDropDown inherit from globAddable to expose the setID (and implicitly getID) methods.

所有这些的最终结果是完全相同的.单击DayDropDown上的按钮时,在MonthDropDown上使用不同的值进行测试后,仍然看不到我的一天DropDown,再次出现"ReferenceError:弱引用对象不再存在"错误.但是,我注意到有问题的行实际上是打开下拉菜单的方法(drop.open(ddRoot),在我的.kv文件的第114行上调用).这仍然不能完全给我足够的信息来知道导致错误的过程的哪一部分,无论是将按钮添加到DropDown还是简单地调用open方法.有了这些新信息,有谁能够推断出需要改变的地方?

The net result of all this is exactly the same. I still don't see my day DropDown when clicking the button on DayDropDown, and after testing with different values on the MonthDropDown, again I get the 'ReferenceError: weakly-referenced object no longer exists' error. However, I am noticing that the offending line is actually the method that opens the dropdown (drop.open(ddRoot), which is called on line 114 of my .kv file). This still doesn't quite give me enough information to know which part of the process is causing the error, be it the adding of the buttons to the DropDown or simply the calling of the open method. Given this new information, is anyone able to deduce what needs to change?

推荐答案

好吧,我终于弄清楚了这一点.

Alright, I finally figured this one out.

我的ReferenceError不是我的方法导致的,而是我在DropDown对象实现方面的一个基本误解.解决方法只是

My ReferenceError was not a result of my methods, but rather a fundamental misunderstanding on my part of the implementation of DropDown objects. The fix was simply

<DayDropDown>:
    drop: drop.__self__
    ...

这使我花了很长时间才能找到,但是以

This took me one heck of a long time to find, but came in the form of this documentation. Seeing as no other posts mentioning these ReferenceErrors makes any mention to this document, I'm leaving it here for others to use in case they run into a similar issue.

这篇关于向DropDown添加可变数量的控件-弱引用对象不再存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆