【问题标题】:Kivy: Screen containing ScrollView, StackLayout and Labels is all out of placeKivy:包含 ScrollView、StackLayout 和 Labels 的屏幕完全不合适
【发布时间】:2020-05-09 10:27:34
【问题描述】:

我想要一个包含 StackLayout 的屏幕。这个 StackLayout 包含几个短到长的标签。 StackLayout 的全部内容也应该可以使用 ScrollView 滚动。我尝试了下面的设置,但基本上每个标签都不合适。根据我对 kivy 文档和互联网上(有些)类似问题的理解,我尝试了几种替代设置,但它们都没有真正奏效。

这是代码的最小工作版本:

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window

Window.size = (350, 600)


class RootWindow(Screen):
    def __init__(self, **kwargs): 
        super(RootWindow, self).__init__(**kwargs)

        self.searchButton = Button(text="Search",
                                   size_hint=(1,0.8))
        self.searchButton.bind(on_press=self.search)
        self.add_widget(self.searchButton)
        # some irrelevant code

    def search(self,instance):

        #here some omitted code which grabs some strings from a SQLite db and saves results in src, ingsList and steps

        src = 'Lorem ipsum'
        ingsList = ['Lorem', 'ipsum', 'dolor', 'sit amet']
        WMan.transition.direction = 'left'
        WMan.current = 'second'

        # theses should be aligned at center of the screen
        WMan.current_screen.title.add_widget(Label(text=src,
                                                   size_hint=(1,None)))

        WMan.current_screen.ingredients.add_widget(Label(text="Ingredients:",
                                                           text_size=(self.width, None),
                                                           size_hint=(1,None),
                                                           height='30sp'))
        # these should be left aligned
        for i in range(0,len(ingsList)):
            WMan.current_screen.ingredients.add_widget(Label(text=ingsList[i],
                                                                  text_size=(self.width, None),
                                                                  size_hint=(0.9,None),
                                                                  height='20sp'))
        # center aligned
        WMan.current_screen.ingredients.add_widget(Label(text="Steps:",
                                                           text_size=(self.width, None),
                                                           size_hint=(1,None),
                                                           height='30sp'))

        # this should be left aligned (or, ideally, justified)
        steps = "Duis finibus risus tempor nisl scelerisque, quis facilisis augue pretium. Nullam sit amet nibh ex. Pellentesque lobortis eget ipsum a congue. Nunc luctus odio sit amet arcu interdum, id pharetra urna semper. Proin at turpis vel neque facilisis pretium ut sed massa. Phasellus elit diam, elementum at tempus non, eleifend quis libero. Integer convallis tortor eget mattis eleifend."
        WMan.current_screen.ingredients.add_widget(Label(text=steps,
                                                                       text_size=(self.width, None),
                                                                       size_hint=(1,None),
                                                                       pos_hint=(None,None),
                                                                       height='10sp'
                                                                       ))



class SecondWindow(Screen):
    def __init__(self, **kwargs): 
        super(SecondWindow, self).__init__(**kwargs)

        self.title = StackLayout(pos_hint={"x":0.05, "top":0.9},
                                 size_hint = (0.9,0.2))
        self.add_widget(self.title)

        self.ingredients = StackLayout(pos_hint={"x":0.05, "top": 0.8},
                                       size_hint=(0.9,None),
                                       size_hint_y=None,
                                       orientation='lr-tb',
                                       spacing = (0,2))
        self.ingredients.bind(minimum_height = self.ingredients.setter('height'))

        self.scroll = ScrollView(size_hint=(1,None),
                                 size=(self.width, Window.height),
                                 pos_hint={"x": 0.05, "top":0.8})
        self.scroll.add_widget(self.ingredients)
        self.add_widget(self.scroll)

WMan = ScreenManager()
WMan.add_widget(RootWindow(name='root'))  
WMan.add_widget(SecondWindow(name='second'))

class MyApp(App):
    def build(self):
        return WMan


if __name__ == "__main__":
    MyApp().run()

【问题讨论】:

    标签: python kivy scrollview stacklayout


    【解决方案1】:

    使用kv 语言更容易解决这个问题。这是您的代码的修改版本,可以满足您的要求:

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.button import Button
    from kivy.uix.label import Label
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.core.window import Window
    
    Window.size = (350, 600)
    
    class LeftAlignedLabel(Label):
        pass
    
    Builder.load_string('''
    <LeftAlignedLabel>:
        size_hint: 1, None
        height: '20sp'
        text_size: self.size
        halign: 'left'
    <SecondWindow>:
        StackLayout:
            id: title_stack
            pos_hint: {"x":0.05, "top":0.9}
            size_hint: (0.9,0.2)
            Label:
                id: title
                size_hint: (1, None)
                height: self.texture_size[0]
        ScrollView:
            id: scroll
            size_hint: (0.9,0.7)
            pos_hint: {"x": 0.05, "top":0.7}
            StackLayout:
                size_hint: (0.9,None)
                orientation: 'lr-tb'
                spacing: (0,2)
                height: self.minimum_height
                Label:
                    text: 'Ingredients:'
                    size_hint: (1,None)
                    text_size: self.size
                    halign: 'left'
                    height: '30sp'
                BoxLayout:
                    id: ingredients
                    orientation: 'vertical'
                    size_hint: (1, None)
                    height: self.minimum_height
                Label:
                    text: 'Steps:'
                    size_hint: (1,None)
                    height: '30sp'
                Label:
                    id: steps
                    text_size: (self.width, None)
                    size_hint: (1,None)
                    height: self.texture_size[1]  # adjusts height according to text
    ''')
    
    
    class RootWindow(Screen):
        def __init__(self, **kwargs):
            super(RootWindow, self).__init__(**kwargs)
    
            self.searchButton = Button(text="Search",
                                       size_hint=(1,0.8))
            self.searchButton.bind(on_press=self.search)
            self.add_widget(self.searchButton)
            # some irrelevant code
    
        def search(self,instance):
    
            #here some omitted code which grabs some strings from a SQLite db and saves results in src, ingsList and steps
    
            src = 'Lorem ipsum'
            ingsList = ['Lorem', 'ipsum', 'dolor', 'sit amet']
    
            WMan.transition.direction = 'left'
            WMan.current = 'second'
    
            # theses should be aligned at center of the screen
            # WMan.current_screen.title.add_widget(Label(text=src,
            #                                            size_hint=(1,None)))
            WMan.current_screen.ids.title.text = src
    
            # these should be left aligned
            for i in range(0,len(ingsList)):
                WMan.current_screen.ids.ingredients.add_widget(LeftAlignedLabel(text=ingsList[i]))
    
            # this should be left aligned (or, ideally, justified)
            steps = "Duis finibus risus tempor nisl scelerisque, quis facilisis augue pretium. Nullam sit amet nibh ex. Pellentesque lobortis eget ipsum a congue. Nunc luctus odio sit amet arcu interdum, id pharetra urna semper. Proin at turpis vel neque facilisis pretium ut sed massa. Phasellus elit diam, elementum at tempus non, eleifend quis libero. Integer convallis tortor eget mattis eleifend."
            WMan.current_screen.ids.steps.text = steps
    
    
    class SecondWindow(Screen):
        pass
    
    
    WMan = ScreenManager()
    WMan.add_widget(RootWindow(name='root'))
    WMan.add_widget(SecondWindow(name='second'))
    
    
    class MyApp(App):
        def build(self):
            return WMan
    
    
    if __name__ == "__main__":
        MyApp().run()
    

    LeftAlignedLabel 类用于使成分列表左对齐。

    此外,使用kv 语言可以更轻松地查看有问题的结构。例如,标题Label 是第一个StackLayout 的唯一子项。通常,如果您不打算添加其他子级,则可以将只有一个子级的布局替换为只有一个子级。

    【讨论】:

    • 谢谢约翰。你说服我最终将我的布局代码移动到一个 kv 文件。这完全符合预期。
    猜你喜欢
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    相关资源
    最近更新 更多