我正在努力学习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:

  1. 您可以使用 on_selection change.据我所知没有 on_selected_item.

  2. 在创建对象之前,您正在绑定事件.以下说明在 初始化:

    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)
    
  3. MainLayout 不包含任何适配器。在方法 on_enter, ,参考文献 self.adapter 应改为 adapter (方法的参数)或 self.apps_list.adapter.

  4. 创建引用的方式 domain, apps_listlogo100 很奇怪。我不知道 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 这取代了适配器。你的例子太不完整了,不知道如何或何时调用后者,但是如果它发生在你点击列表项之前,你的事件永远不会被触发,因为它绑定到的适配器已经被替换。这会给你看到的行为。要修复它,不要替换适配器,也不要将回调重新绑定到新的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top