我在获取kivy.DropDown小部件以与屏幕管理器配合使用时遇到问题。
我正在使用kivy文档提供的下拉代码,并将其添加到屏幕小部件,然后将其添加到屏幕管理器以显示。以下代码应单独重现该问题。
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.anchorlayout import AnchorLayout
class MyScreen(Screen):
def __init__(self, **kwargs):
super(MyScreen, self).__init__(**kwargs)
anchor = AnchorLayout()
anchor.anchor_x = "center"
anchor.anchor_y = "center"
anchor.size = self.size
anchor.pos = self.pos
dropdown = DropDown()
for index in range(10):
# When adding widgets, we need to specify the height manually
# (disabling the size_hint_y) so the dropdown can calculate
# the area it needs.
btn = Button(text='Value %d' % index, size_hint_y=None, height=44)
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: dropdown.select(btn.text))
# then add the button inside the dropdown
dropdown.add_widget(btn)
# create a big main button
mainbutton = Button(text='Hello', size_hint=(None, None))
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
mainbutton.bind(on_release=dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))
anchor.add_widget(mainbutton)
self.add_widget(anchor)
sm = ScreenManager() # transition = NoTransition())
sm.add_widget(MyScreen(name='screen'))
class MyApp(App):
def build(self):
return sm
if __name__ == '__main__':
MyApp().run()
为什么将其放入ScreenManager内的屏幕小部件中后,下拉小部件不起作用?欢迎澄清。
PS: 对于发现此问题的任何人,您都可以使用微调控件来实现相同的功能。
答案 0 :(得分:1)
我相信您的问题是由于垃圾收集造成的。 dropdown
方法中的__init__()
引用未保存(bind
使用weakref
不会阻止垃圾回收)。因此,我认为您所需要做的就是将dropdown
局部变量替换为self.dropdown
实例变量,如下:
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.anchorlayout import AnchorLayout
class MyScreen(Screen):
def __init__(self, **kwargs):
super(MyScreen, self).__init__(**kwargs)
anchor = AnchorLayout()
anchor.anchor_x = "center"
anchor.anchor_y = "center"
anchor.size = self.size
anchor.pos = self.pos
self.dropdown = DropDown()
for index in range(10):
# When adding widgets, we need to specify the height manually
# (disabling the size_hint_y) so the dropdown can calculate
# the area it needs.
btn = Button(text='Value %d' % index, size_hint_y=None, height=44)
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: self.dropdown.select(btn.text))
# then add the button inside the dropdown
self.dropdown.add_widget(btn)
# create a big main button
mainbutton = Button(text='Hello', size_hint=(None, None))
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
mainbutton.bind(on_release=self.dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
self.dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))
anchor.add_widget(mainbutton)
self.add_widget(anchor)
sm = ScreenManager() # transition = NoTransition())
sm.add_widget(MyScreen(name='screen'))
class MyApp(App):
def build(self):
return sm
if __name__ == '__main__':
MyApp().run()