【问题标题】:Get value from kivy text input in kv during build在构建期间从 kv 中的 kivy 文本输入中获取值
【发布时间】:2015-05-13 02:51:27
【问题描述】:

我有三个问题/问题:

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

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()

还有一些app.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

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    我会尽力解决你的问题:

    1) 查看您的代码,ButtonsFactory 只是一个BoxLayout,它是一个容纳其他小部件的容器。 self.build 函数创建CustomButton 小部件并将它们放入容器中。如果您不调用self.build,则不会将任何内容添加到容器中并且您有一个空的(空白)BoxLayout

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

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

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

    另一个问题是您将BoxLayout(您的ButtonsFactory)放入ScrollViewerBoxLayout 将调整自身大小以完全适合 ScrollViewer 内部,因此它不会滚动。您需要通过清除 size_hint 来覆盖此行为。详情请见this SO question

    【讨论】:

    • 首先感谢您的关注和帮助。继续,1.我明白,但我认为重点是 Kivy 调用 build 本身?也许它只对小部件有效。 2. 和 4. 理解。 3. 嗯,这就是问题所在。正如您可能注意到的那样,我尝试设置和使用此属性,但我能够做到的唯一方法是将其设置为 app.property,并在构建函数中修改(设置默认值)。我不认为这是一个很好的解决方案,但它仍然有效,建议提供了巨大的帮助。
    • 当然可以。您正在考虑的build 函数是App.build,kivy 调用它来获取应用程序的根小部件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    相关资源
    最近更新 更多