如何在Kivy中定位小部件并使用布局?

时间:2017-03-18 23:16:57

标签: python kivy

这:(https://imgur.com/a/Y9Xwl)(由于某种原因无法格式化)是我目前正在Kivy中创建的用户界面。我很难重新创建这个,因为我不了解布局系统,我已经阅读了很多文档,观看了很多Youtube视频,修改了代码,但仍然无法得到理想的结果。到目前为止,这是我的代码,它包含我需要的所有小部件,它们只是没有按照我想要的大小/定位:

from kivy.app import App
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button

from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

class CaloriesScreen(Screen):
    pass

class categoriesScreen(Screen):
    pass

class loginScreen(Screen):
    pass

class registerScreen(Screen):
    pass

class shoppingListScreen(Screen):
    pass

class theScreenManager(ScreenManager):
    pass

root_widget = Builder.load_string('''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition

theScreenManager:
    transition: FadeTransition()
    CaloriesScreen:

<CaloriesScreen>:
    name: 'calories'
    BoxLayout:
        orientation: 'vertical'

        BoxLayout:
            orientation: 'horizontal'
            size_hint: 1, .3
            Button:
                text: '<'
                size_hint: .1, 1
                font_size: 75
                background_normal: ""
                background_color: 0.18, .5, .92, 1
                on_release: app.root.current = 'main' 

            Label:
                text: 'Calories'
                halign: 'left'
                font_size: 50
                canvas.before:
                    Color:
                        rgb: 0.18, .5, .92
                    Rectangle:
                        pos: self.pos
                        size: self.size
            Widget:
                size_hint: .1, 1
                canvas.before:
                    Color:
                        rgb: 0.18, .5, .92
                    Rectangle:
                        pos: self.pos
                        size: self.size

        BoxLayout:
            orientation: 'horizontal'
            size_hint: 1, .4
            canvas.before:
                Color:
                    rgb: 0.8, 0.8, 0.8
                Rectangle:
                    pos: self.pos
                    size: self.size
            Label:
                text: 'Recipes'
                font_size: 30
                color: 0.18, .5, .92, 1
                size_hint: 1, 1


            Button:
                id: btn
                text: 'Select a recipe...'
                on_release: dropdown.open(self)
                height: '48dp'
                size_hint: .5, .3
                pos: self.x, .3

            DropDown:

                id: dropdown
                on_parent: self.dismiss()
                on_select: btn.text = '{}'.format(args[1])


                Button:
                    text: 'First recipe'
                    size_hint_y: None
                    height: '48dp'
                    on_release: dropdown.select('First Item')

                Button:
                    text: 'Second recipe'
                    size_hint_y: None
                    height: '48dp'
                    on_release: dropdown.select('Second Item')

                Button:
                    text: 'Third recipe'
                    size_hint_y: None
                    height: '48dp'
                    on_release: dropdown.select('Third Item')


            Button:
                text: '+'
                font_size: 30
                background_normal: ""
                background_color: 0.18, .5, .92, 1
                #on_release:

        BoxLayout:
            orientation: 'vertical'
            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'Food'
                    font_size: 30
                    color: 0.18, .5, .92, 1
                Label:
                    text: 'Cal'
                    font_size: 30
                    color: 0.18, .5, .92, 1
            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'Simple Cheese Omelette'
                    font_size: 30
                    color: 0.18, .5, .92, 1
                Label:
                    text: '241'
                    font_size: 30
                    color: 0.18, .5, .92, 1
            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'Burger'
                    font_size: 30
                    color: 0.18, .5, .92, 1
                Label:
                    text: '295'
                    font_size: 30
                    color: 0.18, .5, .92, 1
            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'Tomato and caper linguine '
                    font_size: 30
                    color: 0.18, .5, .92, 1
                Label:
                    text: '393'
                    font_size: 30
                    color: 0.18, .5, .92, 1
        BoxLayout:
            orientation: 'vertical'
            canvas.before:
                Color:
                    rgb: 0.8, 0.8, 0.8
                Rectangle:
                    pos: self.pos
                    size: self.size
            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'Total Cal'
                    font_size: 30
                    color: 0.18, .5, .92, 1
                Label:
                    text: '929'
                    font_size: 30
                    color: 0.18, .5, .92, 1
            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'You are under calories'
                    font_size: 30
                    color: 0.18, .5, .92, 1
            Button:
                text: 'Clear'
                font_size: 75
                background_normal: ""
                background_color: 0.18, .5, .92, 1
                #on_release:


''')

class RecipeApp(App):
    def build(self):
        return root_widget

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

这个(https://imgur.com/a/zW2z0)(由于某种原因无法格式化)是该代码的输出结果。带有“&lt;”的顶栏按钮是我想要的,我只试图编辑它下面的水平行小部件。我无法在下拉菜单中找到我想要的“选择您的食谱”标签。我试过多次改变它的y轴,但它总是下沉到boxlayout的底部。我甚至尝试给它一个新的boxlayout只是为了下拉并尝试做:pos:self.parent.x,self.parent.y * 0.5假设它将在它的父布局(boxlayout)的y轴的中间位置但是依然没有。我想知道是否最好只使用一个floatlayout并手动定位所有小部件,但我不确定当我将它编译成Android设备的APK时这将如何工作。将我的小部件放在屏幕上的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

使用pos_hint
如果pos_hint: {'top': 1},窗口小部件的顶部将会触及父框的顶部 因此,如果您的小部件高度为其父框(size_hint: 0.5, 0.3)的30%,并且您希望它垂直居中,则需要pos_hint: {'top': 0.5 + 0.3/2},这意味着小部件的顶部将位于屋顶+小部件高度的一半,即父箱的15% 这需要我们65%到顶部:)

size_hint: 0.5, 0.3
pos_hint: { 'top' : 0.65}

如果小部件size_hint是动态的,你可以做这样的事情。

pos_hint: {'top': 0.5 + self.size_hint[1]/2}

然后以Select recipe按钮为例:

Button:
    id: btn
    text: 'Select a recipe...'
    on_release: dropdown.open(self)
    height: '48dp'
    size_hint: .5, .3
    pos_hint: {'top': 0.5 + self.size_hint[1]/2}