В моем приложении я создаю экземпляры ModalView, которые содержат дочерние виджеты с обратными вызовами, которые привязаны к свойствам виджетов или запланированы с помощью Clock. Вот пример кода, чтобы продемонстрировать это. Я обнаружил, что метод dismiss()
экземпляра ModalView оставляет нетронутыми привязки обратного вызова и запланированные обратные вызовы Clock его дочерних виджетов. Я должен позаботиться о том, чтобы освободить и распланировать их сам. Это может запутаться, когда я связываюсь с обратными вызовами, которые принимают аргументы (тогда я должен использовать методы fbind
и funbind_uid
, сохраняя при этом uid
s). Точно так же запланированные обратные вызовы Clock, которые принимают аргументы, являются непростыми для планирования, так как тогда они являются анонимными, будучи запланированными с использованием лямбда-выражения или частичного.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.modalview import ModalView
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.clock import Clock
import datetime
Builder.load_string('''
#: kivy 1.9.2
<MainWidget>:
Button:
text: 'Push the button (pu-push the button)'
on_press:
root.showtime()
''')
class MyWidget(FloatLayout):
text=StringProperty() # this can be bound to 'text' property of a child widget for observation
timenow=ObjectProperty()
def __init__(self, **kwargs):
super(FloatLayout, self).__init__(**kwargs)
self.bind(timenow=self.update_text)
Clock.schedule_interval(self.poll_datetime, .5)
def poll_datetime(self, dt):
self.timenow = datetime.datetime.now()
print "polling datetime"
def update_text(self, *args):
self.text=self.timenow.strftime("%Y-%m-%d %H:%M:%S")
print "updating text"
def cleanup(self, *args):
self.unbind(timenow=self.update_text)
Clock.unschedule(self.poll_datetime)
print "cleaning up"
class MainWidget(FloatLayout):
def __init__(self, **kwargs):
super(MainWidget, self).__init__(**kwargs)
def showtime(self):
overlay = ModalView()
container=MyWidget()
timelabel=Label()
container.bind(text=timelabel.setter('text'))
container.bind(pos=timelabel.setter('pos'))
container.add_widget(timelabel)
cancelbutton=Button(text='Cancel', size_hint=(None, None))
cancelbutton.bind(on_press=container.cleanup)
cancelbutton.bind(on_press=overlay.dismiss)
container.add_widget(cancelbutton)
overlay.add_widget(container)
overlay.open()
class MyApp(App):
def build(self):
mw=MainWidget()
return mw
if __name__ == '__main__':
MyApp().run()
Я правильно делаю? Метод ModalView
dismiss()
оставляет другие объекты, о которых я даже не подозреваю? Какой хороший способ обнаружить такие объекты, оставленные позади? Есть ли способ обеспечить полное уничтожение дочерних виджетов экземпляра ModalView
при dismiss()
?