在构建期间从kv中的kivy文本输入中获取值

时间:2015-05-12 13:05:22

标签: python kivy

我有三个问题/问题:

  1. 给出app / app kv文件的以下配置为什么我必须在ButtonsFactory类中调用self.build()。如果我删除它,我得到黑屏,可能是因为kv文件中没有根元素,但如果我尝试制作MainView根元素,我最终也会使用黑屏。
  2. 第二个问题,是否可以在我的someapp.kv文件中设置自定义按钮的最小高度?它们永远不应低于X.
  3. 最后但对我来说最重要为什么我无法在类函数get_list_of_files()中从kv文件中获取TextInput的text属性?什么是解决这个问题的最佳方法?在python代码中对此值进行硬编码的全局变量?在python代码之前移动Builder(将kv嵌入为字符串)?
  4. 最后一个问题...按钮“填充”scrollview_id而不是保留大小并在此视图中可滚动,我希望它们停止自我调整大小。
  5. someapp.py文件

    from kivy.app import App
    from kivy.factory import Factory
    from kivy.properties import ObjectProperty, StringProperty
    # views
    from kivy.uix.modalview import ModalView
    # layouts
    from kivy.uix.boxlayout import BoxLayout
    
    import os
    
    # defined in kv file.
    class HeaderContainer(BoxLayout): pass
    class ButtonsContainer(BoxLayout): pass
    class MainView(ModalView): pass
    
    class ButtonsFactory(BoxLayout):
        target_location = StringProperty(None)
        def __init__(self, *args, **kwargs):
            super(ButtonsFactory, self).__init__(*args, **kwargs)
    
            self.build() # Question 1: is that neccessary? (i think not, but black screen without it, why?)
    
        def build(self):
            self.orientation = "vertical"
            for file_name in self.get_list_of_files():
                btn = Factory.CustomButton()
                with open(file_name, 'r') as test_file:
                    btn.file_name = test_file.readline().strip()[1:20]
                btn.nice_name = file_name  # Question 2: is it possible to set minimum height for kivy button? (havent found in api)
                self.add_widget(btn)
            # print ("1.!!!!!!", self.target_location) == NONE
        @classmethod
        def get_list_of_files(cls):
            # print "2.!!!!!!", repr(cls.target_location) == <kivy.properties.StringProperty object at 0x7f1dd7596e20> 
            dir_ = "/tmp" #dir_ = cls.target_location
            try:
                files = [os.path.join(dir_, name) for name in os.listdir(dir_)
                         if os.path.isfile(os.path.join(dir_, name))]
            except (OSError, IOError):
                files = []
            return files
    
    class SomeApp(App):
        def on_pause(self):
            pass
        def on_resume(self):
            pass
        def build(self):
            return MainView()
    
    if __name__ == '__main__':
        SomeApp().run()
    

    和someapp.kv文件

    #:kivy 1.8.0
    #:import platform platform
    
    <CustomButton@Button>:
        file_name: ''
        nice_name: ''
        text: root.nice_name + "\n" + root.file_name
        halign:'center'
        size_hint:(1, 0.1)
    
    <HeaderContainer>:
        id: header_layout
        size_hint:(1, 0.1)
        orientation:'horizontal'
        # 2-nd-try # target_location: textinput_target_location.text
        # I was trying here to pass by ObjectProperty (or StringProperty) but unfortunately failed.
        TextInput:
            size_hint:(0.7, 1)
            id: textinput_target_location
            multiline: False
            hint_text: "path where stress files are stored, default /sdcard/appdir"
            text: "/tmp" if platform.machine() in ["x86_64", "i686", "i386"] else "/sdcard/appdir/"  # arm "arm7l", but also other arm's
            #on_text: my_callback_to_reload_dir_contents()
        Button:
            size_hint:(0.2, 1)
            id: read_target_location
            text: "read target_location directory"
            #on_release: my_callback_to_reload_dir_contents()
    
    <ButtonsContainer>:
        size_hint:(1, 0.9)
        orientation:'vertical'
        ScrollView:
            id: scrollview_id
            orientation: 'vertical'
            ButtonsFactory
    
    
    <MainView>:
        BoxLayout:
            # 1-st-try # target_location: HeaderContainer.target_location
            id: main_layout
            padding:10
            spacing: 5
            orientation:'vertical'
            HeaderContainer
            # n-th-try # target_location: HeaderContainer.target_location
            ButtonsContainer
    

1 个答案:

答案 0 :(得分:0)

我会尝试解决您的问题:

1)查看代码时,ButtonsFactory只是一个BoxLayout,它是用于保存其他小部件的容器。 self.build函数创建CustomButton小部件并将它们放入容器中。如果您不打电话给self.build,则不会向容器添加任何内容,而您有空(空白)BoxLayout

2)这有点复杂,因为高度通常由容器小部件控制。您可以通过将size_hint属性设置为None并指定高度来手动设置小部件的高度。

3)如果可以避免,我绝不会使用全局变量。在这种情况下,如果您只需要访问TextInput的文本内容,我会将其绑定到附加到您可以访问的小部件的StringProperty或App对象本身(可以在.kv中的任何位置访问)为app.<property>

4)同样,高度由小部件所在的容器控制(a BoxLayout)。您可以通过在小部件上将size_hint设置为无来手动控制其大小。

另一个问题是,您将BoxLayoutButtonsFactory)放在ScrollViewer内。 BoxLayout会自行调整大小以适应ScrollViewer内部,因此不会滚动。{1}}您需要通过清除size_hint来覆盖此行为。有关详细信息,请参阅this SO question