Kivy,listview没有属性'selection'
-
20-12-2019 - |
题
我正在努力学习kivy :如何操作listview及其元素绑定。这是我的代码的一部分,我有一个问题。
编辑:我更改了代码,或者更确切地说,将其全部添加,而不仅仅是发布一部分。
import re
import sys
import json
import requests
import datetime
from datetime import datetime
from random import randint
import time
#Kivy Imports
import kivy
from kivy.app import App
from kivy.uix import label
from kivy.uix.image import Image
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.properties import StringProperty, ObjectProperty
from kivy.adapters.listadapter import ListAdapter
from kivy.uix.listview import ListView, ListItemButton
from kivy.lang import Builder
from kivy.adapters import dictadapter
from kivy.uix.modalview import ModalView
#Kivy version
kivy.require('1.7.0')
#MainLayout Class with the GridView
class MainLayout(GridLayout):
def __init__(self, **kwargs):
super(MainLayout, self).__init__(**kwargs)
self.text_input = ObjectProperty() #reference to the textinput from .kv
self.apps_list = ObjectProperty()
self.logo100 = ObjectProperty()
self.domain = self.ids.text_input.text
self.apps_list = self.ids.apps_list
self.logo100 = self.ids.logo100
self.apps_list.adapter.bind(on_selected_item=self.callback)
def on_enter(self):
apps = {'a', 'b', 'c', 'd', 'e' ,'f', 'g'}
if apps != None :
list_adapter = ListAdapter(data = apps,
selection_mode = 'single',
allow_empty_selection = True,
cls = ListItemButton,
sorted_keys=[])
self.apps_list.adapter = list_adapter
def callback(self, adapter):
if len(self.adapter.selection) == 0:
print "No selected item"
else:
print self.adapter.selection[0].text
class WabApp(App):
def build(self):
return MainLayout()
if __name__ == '__main__':
WabApp().run()
为了。我使用的kv文件 :
<MainLayout>:
rows: 2
orientation: 'horizontal'
GridLayout:
cols: 2
orientation: 'vertical'
row_force_default: True
row_default_height: 50
Image:
id: logo100
source: 'logo100.png'
size_hint: [.2, .1]
texture: self.texture
size: self.texture_size
TextInput:
id: text_input
markup: True
text: ''
font_size: 32
size_hint: [1.8, .1]
multiline: False
on_text_validate: root.on_enter()
hint_text: 'test'
ListView:
id: apps_list
allow_empty_selection: True
当我点击列表中的一个项目时,没有任何反应。
也不知道该不该用 :
self.apps_list.adapter.bind(on_selected_item=self.callback)
或
self.apps_list.adapter.bind(on_selection_change=self.callback)
实际上,第一个和第二个都没有在控制台上显示一个单词。有什么建议吗?
解决方案
有几件事情你做错了,但你的主要错误是以下列表的数字2:
您可以使用
on_selection change
.据我所知没有on_selected_item
.在创建对象之前,您正在绑定事件.以下说明在 初始化:
self.apps_list.adapter.bind(on_selected_item=self.callback)
但它应该在创建新的on_enter
ListAdapter
.它可能是该方法的最后一行。请参阅下面的代码。def on_enter(self): ... self.apps_list.adapter = list_adapter self.apps_list.adapter.bind(on_selection_change=self.callback)
MainLayout
不包含任何适配器。在方法on_enter
, ,参考文献self.adapter
应改为adapter
(方法的参数)或self.apps_list.adapter
.创建引用的方式
domain
,apps_list
和logo100
很奇怪。我不知道ids
属性在Widget
但你可以直接使用它。所以,而不是:self.apps_list.adapter = list_adapter
您可以使用:
self.ids.apps_list.adapter = list_adapter
没有必要超载 _初始化_方法在所有。
如果您不想访问 apps_lists
通过 ids
属性,那么就可以在kivy语言的header中添加属性:
<MainLayout>:
text_input: text_input
apps_list: apps_list
logo100: logo100
rows: 2
这是最终的工作python代码,其中包括所有提到的更改。我省略了进口。
# ... your imports
class MainLayout(GridLayout):
def on_enter(self):
apps = {'a', 'b', 'c', 'd', 'e' ,'f', 'g'}
if apps != None :
list_adapter = ListAdapter(data = apps, selection_mode = 'single',
allow_empty_selection = True, cls = ListItemButton, sorted_keys=[])
self.apps_list.adapter = list_adapter
self.apps_list.adapter.bind(on_selection_change=self.callback)
def callback(self, adapter):
if len(adapter.selection) == 0:
print "No selected item"
else:
print adapter.selection[0].text
class WabApp(App):
def build(self):
return MainLayout()
if __name__ == '__main__':
WabApp().run()
其他提示
你的代码示例都搞砸了,而且非常不完整?你能给一个简单的工作应用程序显示你的问题吗?
我可以给出一些建议来解决问题,其中一个会导致你看到的行为:
1)你做 self.apps_list = ObjectProperty()
在 __init__
方法。这是错误的,它不会创建一个具有任何有用行为的ObjectProperty,只是创建一个 实例 你的班级,你甚至在下一行替换!相反,您应该在类级别创建属性(即与函数方法相同的级别)。
2)你包括绑定到适配器的代码 on_selection_change
事件,但也代码在 on_enter
这取代了适配器。你的例子太不完整了,不知道如何或何时调用后者,但是如果它发生在你点击列表项之前,你的事件永远不会被触发,因为它绑定到的适配器已经被替换。这会给你看到的行为。要修复它,不要替换适配器,也不要将回调重新绑定到新的。