我在kivy中添加或删除小部件时遇到了一些困难。情况就是这样:
主窗体应包含三个小部件中的两个,Widget1,Widget2和Widget3。按下Widget1的按钮,应该删除Widget2并显示Widget3。
这是main.py文件:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.factory import Factory
class TableApp(App):
def on_pause(self): return True
def on_resume(self): pass
class Form(BoxLayout):
def click(self, instance, arg):
print 'this is the Form class'
print 'this is my arg ... ', arg
print 'this is the button pressed ... ', instance
print 'these are the children of the Form class:', self.children
Form().remove_widget(Widget2)
Form().add_widget(Widget3)
class Widget1(BoxLayout):
def click(self, instance, arg):
print 'this is the Widget 1'
print 'this is my arg ... ', arg
print 'this is my instance', instance, '\n'
Factory.Form().click(instance,arg)
class Widget2(BoxLayout):
pass
class Widget3(BoxLayout):
pass
if __name__ in ('__android__', '__main__'):
TableApp().run()
这是.kv文件:
#:import Factory kivy.factory.Factory
Form:
<Form>:
orientation: 'vertical'
Widget1:
Widget2:
<Widget1>:
Button:
text: "Widget 1 Button"
on_press: root.click(self, 'arg')
<Widget2>:
Button:
text: 'Widget 2 Button'
<Widget3>:
Button:
text: 'Widget 3 Button'
在表格I中,检查Widgets1和2是该类的孩子:
print 'these are the children of the Form class:', self.children
我得到了:
these are the children of the Form class: [<__main__.Widget2 object at 0x7fe5833317c0>, <__main__.Widget1 object at 0x7fe5833316e0>]
因此,当我尝试删除现有的孩子并添加一个新孩子时,我得到了:
TypeError: descriptor 'unbind' of 'kivy._event.EventDispatcher' object needs an argument
有人可以帮忙吗?谢谢。
答案 0 :(得分:3)
大多数问题都是因为您创建了新的小部件而不是使用现有的小部件。
这是一个工作示例(查看注释):
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.factory import Factory #no need for this
class Form(BoxLayout):
def click(self, instance, arg):
print ('this is the Form class')
print ('this is my arg ... ', arg)
print ('this is the button pressed ... ', instance)
print ('these are the children of the Form class:', self.children)
#notice! here we use self, not Form() which will make a new Form instance
self.remove_widget(self.children[0]) #should be Widget2
self.add_widget(Widget3()) #Here we really want a new widget
class Widget1(BoxLayout):
def click(self, instance, arg):
print ('this is the Widget 1')
print ('this is my arg ... ', arg)
print ('this is my instance', instance, '\n')
self.parent.click(instance,arg) #changed to use the existing From instance instead of tring to create a new one
class Widget2(BoxLayout):
pass
class Widget3(BoxLayout):
pass
class TableApp(App):
def on_pause(self): return True
def on_resume(self): pass
if __name__ in ('__android__', '__main__'):
TableApp().run()
答案 1 :(得分:1)
您在print
日志中看到子项的唯一原因是因为它们在kv
lang中使用。这根本不起作用:
Form().remove_widget(Widget2)
Form().add_widget(Widget3)
让我们做一点绘画:
App | "Form()" called: # this is how Form (A) gets created
| | |
|- Form (A) | new Form instance created # this is the click event beginning
| | |
|- Widget1 | |- remove_widget of -> Form()
| | | |
| |- Button | new Form instance created -|
| | | |
|- Widget2 | |- remove_widget(class) |
| | ^ |
|- Button | |- crash |
| |
| new Form instance created -|
左边部分是kv
文件的作用,右边部分是你/ python代码。我们拨打已经可用的{kv
} Form
表单A
:
click
方法A
实例的图形表示,即BoxLayout
区域print
没有任何问题,所以它只是通过,instance
可能是Button
个实例(你应该使用{{ 1}},阅读(un)packing arguments)*args
中,A
行会被注意到,这是我绘图的右侧
Form()
将创建一个类Form()
的新实例(与表单A
无关)(这些括号)Form
调用remove_widget
Widget2
&#34; unbind
实例中没有这样的子节点。这些孩子的格式为Form