我有一个下拉列表,其中列出了其中的月份。选择月份后,我尝试使用正确的天数动态填充第二个下拉列表中的按钮。当我这样做时,我得到:
ReferenceError: weakly-referenced object no longer exists
以下是我的参考文件:
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:
<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?
修改
稍微弄清楚我的代码。我创建了一个新类&#34; globAddable&#34;用方法&#34; getID&#34; - 一个简单的返回自我 - 并将setID放在那里。然后我设置我的setID现在将self.getID()分配给一个变量,然后使用该变量作为要添加到globObjects(以前的globIDs)字典的对象。
我还为我的DropDown对象创建了一个新类,名为ExtDropArray,它存在于我的DayDropDown中。我将populate()方法移动到这个新类,以便它可以由Dropdown直接调用,而不是它的父BoxLayout。我使ExtDropArray和ExtDropDown继承自globAddable以公开setID(和隐式getID)方法。
所有这一切的最终结果完全相同。单击DayDropDown上的按钮时,我仍然没有看到我的日DropDown,并且在MonthDropDown上使用不同的值进行测试后,我再次得到了引用错误:弱引用的对象不再存在&#39;错误。但是,我注意到违规行实际上是打开下拉列表的方法(drop.open(ddRoot),在我的.kv文件的第114行调用)。这仍然没有给我足够的信息来知道进程的哪个部分导致错误,无论是向DropDown添加按钮还是只是调用open方法。鉴于这些新信息,是否有人能够推断出需要改变的内容?
答案 0 :(得分:1)
好吧,我终于想出了这个。
我的ReferenceError不是我的方法的结果,而是我对DropDown对象实现的一个基本误解。修复只是
<DayDropDown>:
drop: drop.__self__
...
这让我花了很长时间才找到,但是以this文档的形式出现了。看到没有其他帖子提及这些ReferenceErrors提及本文档,我将其留在这里供其他人使用,以防他们遇到类似的问题。
答案 1 :(得分:0)
官方文档(Kv language Programming Guide)表示要在KV代码中添加“强”引用,例如id_name: id_name.__self__
,但尚不清楚在哪里需要这样做。而且,它没有为我解决ReferenceError: weakly-referenced object no longer exists
错误。
没有的工作是通过将Buildozer添加到buildozer.spec文件的hostpython3
行来迫使Buildozer使用特定版本的requirements
:
python3==3.7.5, hostpython3==3.7.5
还有一点要注意:将以上内容添加到requirements
之后,我回过头去并删除了所有__self__
引用,它仍然可以正常工作,因此显然在Kivy KV语言中不再需要这些。 / p>