Kivy - 函数绑定缺少 'self' 参数
Kivy - missing 'self' argument on function binding
[使用 Kivy 1.9.2-dev0]
基本上,我正在使用 Kivy 开发网络绘图工具。现在我正在尝试让用户添加项目来对网络进行建模。
首先,我主要想在绘图中添加一些节点。为此,我创建了一个 class ButtonPanel,它将包含允许我们实例化不同类型项目的每个按钮。
然后,我为每个要添加的项目创建了不同类型的弹出窗口。这是 "Add a node" GUI 的代码。在这里,我们可以看到 NodePopup class。每次单击按钮 "Add Node" 时都会创建一个 NodePopup 实例。 class 的函数 "checkbox_changed" 是我遇到问题的地方。
class CustomPopup 是一个基础class,它将加载 KV 文件,我所有的 Custom Popups 都将继承自它,因此我不必多次编写它。
我还添加了一个 Decorator "toggle_form",每当 Checkbox 的状态发生变化时都会调用它(因此,每次我们调用 "checkbox_changed" 函数)。
但是,当我点击复选框时,程序崩溃并出现以下错误:
TypeError: checkbox_changed() missing 1 required positional argument:
'self'
我真的不明白为什么会出现此错误,因为我使用 root
关键字调用该函数,据我所知,该关键字指的是根小部件的实例,即,在这种情况下,"NodePopup" class 的一个实例。
为什么我会收到此 TypeError?我该如何解决?
buttonpanel.py:
class ButtonPanel(GridLayout):
btn_layout = ObjectProperty(None)
node_btn = ObjectProperty(None)
build = BooleanProperty(False)
# This method will create a Popup containing a form, allowing us to put some info about the node we want to add.
def create_node(self):
content = NodePopup(cancel=self.cancel)
self._popup = Popup(title="Add a Node", content=content, size_hint=(0.2, 0.5))
if self.build is False:
self._popup.open()
class CustomPopup(BoxLayout):
Builder.load_file(os.path.join(dirname(__file__), 'popups.kv'))
class NodePopup(CustomPopup):
cancel = ObjectProperty(None)
slack_mode = BooleanProperty(False)
form = ObjectProperty(None)
slack_chkbox = ObjectProperty(None)
# Function called everytime we click on a checkbox
@toggle_form
def checkbox_changed(self):
if not self.slack_mode:
print("POPUPS.PY\CHECKBOX_CHANGED CALL\", self.slack_mode)
self.ids['form'].dismissed = False
else:
self.ids['form'].dismissed = True
# Decorator
def toggle_form(func):
def wrapper(self, *args, **kwargs):
if self.slack_chkbox.active:
self.slack_mode = False
else:
self.slack_mode = True
return func()
return wrapper
popups.kv(相关部分):
<NodePopup>:
form: form
slack_chkbox: slack_chkbox
size: root.size
pos: root.pos
orientation: "vertical"
GridLayout:
cols: 2
size_hint: [1, .1]
Label:
text: "Slack Node"
CheckBox:
id: slack_chkbox
active: False
on_release: root.checkbox_changed()
这是有问题的(基本)NodePopup 的图像:
P.S.:
我已经有另一个 class 使用弹出窗口来加载文件。但是当我加载一个网络时,我使用了一个静态函数,我没有得到任何错误,网络被加载并且一切似乎都工作正常。这是否意味着当我想将函数绑定到 Popup 的子项时,我必须只使用 @staticmethod
?
好的,我明白了。错误出在装饰器中...刚刚编辑为
return self.func()
这会导致另一个错误,但我会自己解决的。
[使用 Kivy 1.9.2-dev0] 基本上,我正在使用 Kivy 开发网络绘图工具。现在我正在尝试让用户添加项目来对网络进行建模。
首先,我主要想在绘图中添加一些节点。为此,我创建了一个 class ButtonPanel,它将包含允许我们实例化不同类型项目的每个按钮。
然后,我为每个要添加的项目创建了不同类型的弹出窗口。这是 "Add a node" GUI 的代码。在这里,我们可以看到 NodePopup class。每次单击按钮 "Add Node" 时都会创建一个 NodePopup 实例。 class 的函数 "checkbox_changed" 是我遇到问题的地方。
class CustomPopup 是一个基础class,它将加载 KV 文件,我所有的 Custom Popups 都将继承自它,因此我不必多次编写它。
我还添加了一个 Decorator "toggle_form",每当 Checkbox 的状态发生变化时都会调用它(因此,每次我们调用 "checkbox_changed" 函数)。
但是,当我点击复选框时,程序崩溃并出现以下错误:
TypeError: checkbox_changed() missing 1 required positional argument: 'self'
我真的不明白为什么会出现此错误,因为我使用 root
关键字调用该函数,据我所知,该关键字指的是根小部件的实例,即,在这种情况下,"NodePopup" class 的一个实例。
为什么我会收到此 TypeError?我该如何解决?
buttonpanel.py:
class ButtonPanel(GridLayout):
btn_layout = ObjectProperty(None)
node_btn = ObjectProperty(None)
build = BooleanProperty(False)
# This method will create a Popup containing a form, allowing us to put some info about the node we want to add.
def create_node(self):
content = NodePopup(cancel=self.cancel)
self._popup = Popup(title="Add a Node", content=content, size_hint=(0.2, 0.5))
if self.build is False:
self._popup.open()
class CustomPopup(BoxLayout):
Builder.load_file(os.path.join(dirname(__file__), 'popups.kv'))
class NodePopup(CustomPopup):
cancel = ObjectProperty(None)
slack_mode = BooleanProperty(False)
form = ObjectProperty(None)
slack_chkbox = ObjectProperty(None)
# Function called everytime we click on a checkbox
@toggle_form
def checkbox_changed(self):
if not self.slack_mode:
print("POPUPS.PY\CHECKBOX_CHANGED CALL\", self.slack_mode)
self.ids['form'].dismissed = False
else:
self.ids['form'].dismissed = True
# Decorator
def toggle_form(func):
def wrapper(self, *args, **kwargs):
if self.slack_chkbox.active:
self.slack_mode = False
else:
self.slack_mode = True
return func()
return wrapper
popups.kv(相关部分):
<NodePopup>:
form: form
slack_chkbox: slack_chkbox
size: root.size
pos: root.pos
orientation: "vertical"
GridLayout:
cols: 2
size_hint: [1, .1]
Label:
text: "Slack Node"
CheckBox:
id: slack_chkbox
active: False
on_release: root.checkbox_changed()
这是有问题的(基本)NodePopup 的图像:
P.S.:
我已经有另一个 class 使用弹出窗口来加载文件。但是当我加载一个网络时,我使用了一个静态函数,我没有得到任何错误,网络被加载并且一切似乎都工作正常。这是否意味着当我想将函数绑定到 Popup 的子项时,我必须只使用 @staticmethod
?
好的,我明白了。错误出在装饰器中...刚刚编辑为
return self.func()
这会导致另一个错误,但我会自己解决的。