我尝试使用Kivy在Python中编写一个简单的界面,包含4个元素:顶部的标题栏,底部的文本输入和旁边的一个小按钮"添加&# 34 ;.在顶部和底部之间我想要一个滚动视图,当我们点击文本输入旁边的按钮时,它会在滚动视图中创建一个新按钮,旁边会有一个小按钮来删除该行(line = the按钮+删除按钮) 要理解:
当我点击" X"要删除的按钮,我有一个错误:
Traceback (most recent call last):
File "nouv_test.py", line 39, in <module>
RunApp().run()
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\app.py", line 828, in run
runTouchApp()
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\base.py", line 504, in runTouchApp
EventLoop.window.mainloop()
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\core\window\window_sdl2.py", line 663, in mainloop
self._mainloop()
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\core\window\window_sdl2.py", line 405, in _mainloop
EventLoop.idle()
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\base.py", line 342, in idle
self.dispatch_input()
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\base.py", line 327, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\base.py", line 233, in post_dispatch_input
listener.dispatch('on_motion', etype, me)
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\core\window\__init__.py", line 1192, in on_motion
self.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\core\window\__init__.py", line 1228, in on_touch_up
if w.dispatch('on_touch_up', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\screenmanager.py", line 1199, in on_touch_up
return super(ScreenManager, self).on_touch_up(touch)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\widget.py", line 479, in on_touch_up
if child.dispatch('on_touch_up', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\relativelayout.py", line 304, in on_touch_up
ret = super(RelativeLayout, self).on_touch_up(touch)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\widget.py", line 479, in on_touch_up
if child.dispatch('on_touch_up', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\widget.py", line 479, in on_touch_up
if child.dispatch('on_touch_up', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\scrollview.py", line 833, in on_touch_up
if self.dispatch('on_scroll_stop', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\scrollview.py", line 872, in on_scroll_stop
self.simulate_touch_down(touch)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\scrollview.py", line 596, in simulate_touch_down
ret = super(ScrollView, self).on_touch_down(touch)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\widget.py", line 457, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\widget.py", line 457, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
File "C:\Users\dvfrg\AppData\Local\Programs\Python\Python36\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
self.dispatch('on_press')
File "kivy\_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy\_event.c:8191)
TypeError: 'NoneType' object is not callable
以下是我的代码(.py / .kv):
# coding: utf-8
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.button import Button
class GUI(ScreenManager):
def __init__(self, **kwargs):
super(GUI, self).__init__(**kwargs)
class Home(Screen):
def __init__(self, **kwargs):
super(Home, self).__init__(**kwargs)
def add_btn(self, grid):
left = Button(text="added", size = (32, 32), size_hint = (1, None)) # the green button
right = Button(background_color = (1,0,0,1), text="X", size = (32, 32), size_hint = (None, None)) # the red DELETE button
right.on_press = self.del_btn(grid, left, right)
grid.add_widget(left)
grid.add_widget(right)
def del_btn(self, grid, L, R): # function called when I click on delete a line
grid.remove_widget(L)
grid.remove_widget(R)
Builder.load_file("nouv_test.kv")
class RunApp(App):
def build(self):
return GUI()
if __name__ == '__main__':
RunApp().run()
.KV:
#: kivy 1.10.0
<GUI>:
Home:
name: "home_screen"
id: home
<Home>:
GridLayout:
rows: 3
Button:
text: u"Mes ann\u00e9es"
size: (50, 50)
size_hint: (1, None)
background_color: (0,1,0,1)
ScrollView:
size_hint:(1, .8)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
do_scroll_x: False
GridLayout:
id: home_scroll_grid
cols: 2
padding: 5
spacing: 5
height: self.minimum_height
size_hint: (1, None)
BoxLayout:
padding: 5
spacing: 5
size: (42, 42)
size_hint: (1, None)
TextInput:
size: (32, 32)
size_hint: (1, None)
Button:
text: "+"
background_color: (0,1,0,1)
size: (32, 32)
size_hint: (None, None)
on_press: root.add_btn(home_scroll_grid)
答案 0 :(得分:2)
您收到NoneType
错误,因为在此声明中right.on_press = self.del_btn(grid, left, right)
,您实际上调用了del_btn
,并且它什么也没有返回。
on_press
采用可调用函数,而不是被调用函数。所以它应该是这样的:right.on_press = self.del_btn
。
但是由于你需要将参数传递给你的回调,你可以使用partial
然后使用.bind
而不是分配给on_press
像这样:
from functools import partial
然后:
right.bind(on_press=partial(self.del_btn, grid, left, right))