2016-03-28 62 views
1

假设我有一个微调ID:水果和值“苹果”,“香蕉”,“西瓜”。Kivy微调指数

我有这样一些代码:

if(self.ids['fruit'].text=='apple'): 
    a=2 

现在,在我的应用我有一个语言选择的选项。所以如果我选择“西班牙语”,我会将苹果换成西班牙语,我的上面的代码将会失败(因为我不会改变它,所以我会保留英文版)。但是选定值的索引将保持不变。

所以,是有kivy微调指数的支持,我的意思是这样:

if(self.ids['fruit'].id==1): 
    a=2 

回答

0

为了保持值(和当前选择)与显示的文本分开,我写了一个Spinner的子类。它将显示值(values)与值的逻辑表示(hidden_values)分开。此外,它有一个额外属性text_transformer,其可变换和selected_valueselected_text(的values当前项)(的hidden_values当前项)转换成显示文本。该代码也包含一个示例。对于我的原始版本(带有原始示例),请看this gist

# -*- coding: utf-8 -*- 

import itertools 
from kivy.factory import Factory 

from kivy.compat import string_types 
from kivy.uix.spinner import Spinner, SpinnerOption 
from kivy.properties import ListProperty, ObjectProperty, StringProperty 
from kivy.logger import Logger 

class HVSpinnerOption(SpinnerOption): 
    """Represents an option in HVSpinner. It adds :attr:`value` to represent a hidden value not shown to user.""" 
    value = ObjectProperty(None) 

class HVSpinner(Spinner): 
    """Implements a spinner that keeps hidden values associated with 
    options and displays a human readable text. 
    """ 

    hidden_values = ListProperty() 
    """Values associated with every item generated from :attr:`values`. 
    :attr:`hidden_values`: is a :class:`~kivy.properties.ListProperty` and defaults to `range(len(self.values))`. 
    The list may contain any kind of object. 
    """ 

    selected_text = StringProperty() 
    """Text representation of the selected item. By default, this is `None`. Upon selection of an item, 
    it will be the corresponding element of :attr:`values`. 
    """ 

    selected_value = ObjectProperty(None) 
    """Representation of the selected item. Defaults to `None`. Upon selection of an item, 
    it will be the corresponding element of :attr:`hidden_values`. 
    """ 

    option_cls = ObjectProperty(HVSpinnerOption) 
    '''Extension of class to display options. It must conform to requirements laid out for :attr:`~kivy.uix.spinner.option_cls`. In addition, the class must have a `value` property (should be :class:`~kivy.properties.ObjectProperty`). 

    Additional :parameter: 
    `text_transformer`: `None` or `callable`. Function that is used to set the :attr:`text` of :class:`HVSpinner` once 
    an item has been selected. It should return a string and it should take 3 arguments: 

    - :attr:`caller`: instance of :class:`HVSpinner` making the call 
    - :attr:`text`: same as :attr:`selected_text` 
    - :attr:`value`: same as :attr:`selected_value` 

    Example:: 

     from kivy.base import runTouchApp 
     from kivy.uix.gridlayout import GridLayout 
     from kivy.uix.boxlayout import BoxLayout 
     def print_current_val(obj, *largs): 
      print "Spinner {} has text [{}], selected_text [{}] and hidden value [{}]".format(obj, obj.text, obj.selected_text, obj.selected_value) 

     def transformator(caller, text, value): 
      return "Now at >{}< ({})".format(text, value) 

     vals = ["item {}".format(i) for i in range(8)] 
     hvals = ["<{}>".format(i + 17) for i in range(len(vals)) ] 
     gl = GridLayout(rows=1) 

     hvs1 = HVSpinner(values=vals, hidden_values=hvals, text='Select Me', 
      size_hint=(.3, None), height="30dp") 
     hvs2 = HVSpinner(values=vals, text='No, Me', size_hint=(.3, None), height="40dp") 
     hvs3 = HVSpinner(values=vals, hidden_values=range(len(vals)), text='Please, me!', size_hint=(.3, None), height="30dp", 
      text_transformer=transformator) 
     hvs1.bind(selected_value=print_current_val) 
     hvs2.bind(selected_value=print_current_val) 
     hvs3.bind(selected_value=print_current_val) 
     gl.add_widget(hvs1) 
     gl.add_widget(hvs2) 
     gl.add_widget(hvs3) 
     runTouchApp(gl) 

    ''' 

    def __init__(self, *args, **kwargs): 
     self.text_transformer = kwargs.pop('text_transformer', None) 
     super(HVSpinner, self).__init__(*args, **kwargs) 

    def _update_dropdown(self, *largs): 
     dp = self._dropdown 
     cls = self.option_cls 
     if isinstance(cls, string_types): 
      cls = Factory.get(cls) 
     dp.clear_widgets() 
     if len(self.hidden_values) == 0: 
      self.hidden_values = range(len(self.values)) 
     if len(self.values) != len(self.hidden_values): 
      Logger.warning("HVSpinner: 'values' and 'hidden_values' have different lengths.") 
     for tv, hv in itertools.izip(self.values, self.hidden_values): 
      item = cls(text=tv, value=hv) 
      item.bind(on_release=lambda option: dp.select((option.text, option.value))) 
      dp.add_widget(item) 

    def _on_dropdown_select(self, instance, data, *largs): 
     if callable(self.text_transformer): 
      self.text = self.text_transformer(self, data[0], data[1]) 
     else: 
      self.text = data[0] 
     self.selected_text = data[0] 
     self.selected_value = data[1] 
     self.is_open = False 

Factory.register('HVSpinner', cls=HVSpinner) 

def main(): 
    from kivy.app import App 
    from kivy.lang import Builder 
    from kivy.clock import Clock 

    kvstr = ''' 
GridLayout: 
    cols: 2 
    HVSpinner: 
     id: my_spinner 
     text: "Pick one" 
     values: ["apple", "banana", "watermelon"] 
    Button: 
     text: "Do something with it!" 
     on_press: app.do_something() 
    Label: 
     text: "Current language: {}".format(app.current_language) 
    Button: 
     text: "Change Language" 
     on_press: app.change_language() 

    ''' 


    item_list = ["apple", "banana", "watermelon"] 
    item_list_spanish = ["manzana", "banana", "sandía"] 


    class AnApp(App): 
     current_language = StringProperty('English') 
     def build(self): 
      Clock.schedule_once(self.set_up_spinner, 0) 
      return Builder.load_string(kvstr) 
     def change_language(self): 
      if self.current_language == 'English': 
       self.current_language = 'Spanish' 
       self.root.ids.my_spinner.values = item_list_spanish 
      else: 
       self.current_language = 'English' 
       self.root.ids.my_spinner.values = item_list 

     def set_up_spinner(self, dt=0): 
      def transformator(caller, text, value): 
       if self.current_language=='English': 
        return "You picked: {}".format(text) 
       else: 
        return "Escogió: {}".format(text) 
      self.root.ids.my_spinner.text_transformer = transformator 
     def do_something(self): 
      if self.root.ids.my_spinner.selected_value == 0: 
       print "An apple was picked!" 

    AnApp().run() 


if __name__ == '__main__': 
    main() 
+0

我很感谢你的努力,但我还是不太了解基维理解它。 :( –

+0

@ user3388005我修改了代码以提供一个接近你想要做的例子。 – zeeMonkeez

0

微调值在ListProperty,因此你可以使用枚举他们是这样的:

for index, text in enumerate(self.ids.fruit.values): 
    if index == 1: 
     a=2 

即使你不能在ListProperty上使用枚举,你仍然可以在你的函数开始时自己创建values的列表。当然枚举从零开始,所以如果你想在你的代码中使用1,那么index + 1将是必要的。