kivy八种布局方式学习

kivy八种布局:FloatLayout、BoxLayout、AnchorLayout、GridLayout、PageLayout、RelativeLayout、ScatterLayout、StackLayout。

FloatLayout:浮动布局,它允许将子部件通过位置参数(pos_hint)和尺寸参数(size_hint)放置在窗口的任意位置.我们用此布局可按窗口大小高度来放置小部件,并且当在不同分辨率的移动设备中,窗口的大小改变时,放置在窗口内的小部件也会相应的调整大小与位置,而不会产生因窗口的大小变化而使布局乱成一团。

from kivy.app import App   #导入kivy的app类,它是所有kivy应用的基类
from kivy.uix.button import Button #引入控件
from kivy.uix.floatlayout import FloatLayout  #引入布局
from kivy.graphics import Rectangle,Color
 
class FloatLayoutApp(App):  #继承app类
    def build(self):  #实现app类的build()方法
        def update_rect(layout,*args):
            #设置背景尺寸,可忽略
            layout.rect.pos=layout.pos
            layout.rect.size=layout.size
 
        float_layout=FloatLayout()
 
        #设置背景颜色(可忽略)
        with float_layout.canvas:
            Color(1,1,1,1)
            float_layout.rect=Rectangle(pos=float_layout.pos,size=float_layout.size)
            float_layout.bind(pos=update_rect,size=update_rect)
 
        #在布局内的【300,200】处添加一个尺寸为0.3,0.2的按钮
        button=Button(text='FloatLayout',size_hint=(.3,.2),pos=(300,200))
        #这里的pos参数不会因窗口改变而改变位置,这个是固定位置,要随窗口变化而动态变化的要用pos_hint
 
        #将按钮添加到布局内
        float_layout.add_widget(button)
        #返回布局
        return float_layout
 
if __name__=='__main__':  #程序入口
        FloatLayoutApp().run() #启动应用程序

BoxLayout:盒子布局,是可以将子部件水平或垂直进行排列的布局,类似Android中的线性布局,如果不设置任何大小,子部件将会以10px的间距平分父窗口的大小。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Rectangle,Color
 
class BoxLayoutWidget(BoxLayout):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
 
        with self.canvas:
            Color(1,1,1,1)
            self.rect=Rectangle(pos=self.pos,size=self.size)
            self.bind(pos=self.update_rect,size=self.update_rect)
 
        self.add_widget(Button(text='hello'))
        self.add_widget(Button(text='BoxLayout'))
 
    def update_rect(self,*args):
        #设置背景尺寸,可忽略
        self.rect.pos=self.pos
        self.rect.size=self.size
 
class BoxApp(App):
    def build(self):
        return BoxLayoutWidget()
 
if __name__ =='__main__':
    BoxApp().run()

AnchorLayout:锚点布局,此布局可以将子部件放置在左上、上中、右上、左中、正中,右中、左下,下中,右下共9个位置处。

from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button
from kivy.graphics import Rectangle,Color
 
class AnchorLayoutWidget(AnchorLayout):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
 
        with self.canvas:
            # Color(1,1,1,1)
            self.rect=Rectangle(pos=self.pos,size=self.size)
            self.bind(pos=self.update_rect,size=self.update_rect)
 
        #嵌套第一个布局
        anchor_first=AnchorLayout(anchor_x='left',anchor_y='top')
        #添加按钮
        anchor_first.add_widget(Button(text='hello',size_hint=[.3,.2],background_color=[0,1,1,1]))
        anchor_first.add_widget(Button(text='hello1',size_hint=[.3,.2],background_color=[1,0,1,1]))
 
        #嵌套第二个布局
        anchor_second=AnchorLayout(anchor_x='right',anchor_y='bottom')
        #添加按钮
        anchor_second.add_widget(Button(text='anchor',size_hint=[.3,.2]))
 
        #添加到父布局中
        self.add_widget(anchor_first)
        self.add_widget(anchor_second)
 
    def update_rect(self,*args):
        #设置背景尺寸
        self.rect.pos=self.pos
        self.rect.size=self.size
 
class AnchorApp(App):
    def build(self):
        return AnchorLayoutWidget()
 
if __name__ =='__main__':
    AnchorApp().run()

GridLayout:网格布局,使用此布局可以将子部件排列成多行多列的矩阵布局。当设定了列数cols或者行数rows后,子部件大小尺寸与子部件个数多少发生变化时,此布局会根据该值进行扩展,但不会超过界限值。

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.graphics import Rectangle,Color
 
class GridLayoutWidget(GridLayout):
    def __init__(self,**kwargs):
        super(GridLayoutWidget, self).__init__(**kwargs)
 
        with self.canvas:
            Color(1,1,1,1)
            self.rect=Rectangle(pos=self.pos,size=self.size)
            self.bind(pos=self.update_rect,size=self.update_rect)
 
        self.padding = 20
        self.spacing = 20
 
        self.cols=3
        for i in range(6):
            btn=Button(text=str(i),background_color=[0,1,1,1],size_hint=[.3,.2])
 
            self.add_widget(btn)
 
    def update_rect(self,*args):
        self.rect.pos=self.pos
        self.rect.size=self.size
 
class GridApp(App):
    def build(self):
        return GridLayoutWidget()
 
if __name__ == '__main__':
    GridApp().run()

PageLayout:与其它布局不司,这是个多页动态布局。此布局可以在窗口内创建多个页面的布局,这些页面可以翻转,每个页面子部件均可作为单独的窗口页面进行开发。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.pagelayout import PageLayout
class PageLayoutWidget(PageLayout):
    def __init__(self,**kwargs):
        super(PageLayoutWidget, self).__init__(**kwargs)
        bt0=Button(text='bt0',background_color=[.3,.9,.3,1])
        bt1=Button(text='bt1',background_color=[.9,.3,.3,1])
        self.add_widget(bt0)
        self.add_widget(bt1)
class PageApp(App):
    def build(self):
        return PageLayoutWidget()
if __name__ =='__main__':
    PageApp().run()

RelativeLayout:相对布局,与FloatLayout基本一致,但它定位属性x、center_x、right、y、center_y、top是相对于上级父布局大小而言的,不是针对窗口的大小。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Rectangle,Color
 
class MyButton(Button):  #自定义控件类
    #自定义一个按钮,提出公共属性
    def __init__(self,**kwargs):
        super(MyButton, self).__init__(**kwargs)
 
        self.font_size=20
        self.size_hint=[0.2,.2]
 
class RelativeLayoutWidget(RelativeLayout):
    pass
 
class BoxLayoutWidget(BoxLayout):
    def __init__(self,**kwargs):
        super(BoxLayoutWidget, self).__init__(**kwargs)
 
        #设置背景颜色
        with self.canvas:
            Color(1,1,1,1)
            self.rect=Rectangle(pos=self.pos,size=self.size)
            self.bind(pos=self.update_rect,size=self.update_rect)
 
        #创建一个RelativeLayout布局
        relative_layout=RelativeLayoutWidget()
 
        #使用自定义按钮
        bt0=MyButton(text='按钮0',pos_hint={'right':1,'top':1},background_color=(.1,.5,.6,1))
        bt1=MyButton(text='按钮1',pos_hint={'x':0,'top':1},background_color=(1,0,0,1))
        bt_relative=MyButton(text='按钮relative',pos_hint={'center_x':0.5,'center_y':0.5},background_color=(.4,.5,.6,1))
        bt2=MyButton(text='按钮2',pos_hint={'x':0,'y':0},background_color=(0,0,1,1))
        bt3=MyButton(text='按钮3',pos_hint={'right':1,'y':0},background_color=(.8,.9,.2,1))
 
        #向RelativeLayout布局内循环添加元素
        for i in [bt0,bt1,bt_relative,bt2,bt3]:
            relative_layout.add_widget(i)
 
        #放一个空的BoxLayout占位
        self.add_widget(BoxLayout())
        #将RelativeLayout添加到布局中
        self.add_widget(relative_layout)
 
    def update_rect(self,*args):
        #设置背景尺寸,可忽略
        self.rect.pos=self.pos
        self.rect.size=self.size
 
class RelativeApp(App):
    def build(self):
        return BoxLayoutWidget()
 
if __name__ =='__main__':
    RelativeApp().run()

ScatterLayout:分散布局,与RelativeLayout类似。当布局更改位置时,布局内的小部件也会跟着父布局一起变动,并且子部件的位置及大小会相对于父布局自动调整,并且此布局还可以进行平移、旋转、缩放布局。

from kivy.app import App
from kivy.uix.image import AsyncImage
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scatterlayout import ScatterLayout
from kivy.graphics import Rectangle,Color
 
class ScatterLayoutWidget(ScatterLayout):
    pass
 
class BoxLayoutWidget(BoxLayout):
        def __init__(self,**kwargs):
            super(BoxLayoutWidget, self).__init__(**kwargs)
 
            with self.canvas:
                Color(1,1,1,1)
                self.rect=Rectangle(pos=self.pos,size=self.size)
                self.bind(pos=self.update_rect,size=self.update_rect)
 
                #创建一个ScatterLayout布局
            scatter_layout=ScatterLayoutWidget()
            #异步加载图片
            image=AsyncImage(source='https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png') #http://sck.rjkflm.com/images/logo1.png
            #将图片添加到ScatterLayout布局中
            scatter_layout.add_widget(image)
            #将ScatterLayout布局嵌套在BoxLayout布局中
            self.add_widget(scatter_layout)
 
        def update_rect(self,*args):
            #设置背景尺寸,可忽略
            self.rect.pos=self.pos
            self.rect.size=self.size
 
 
 
class ScatterApp(App):
    def build(self):
        return BoxLayoutWidget()
 
if __name__ =='__main__':
    ScatterApp().run()

StackLayout:堆栈布局,在此布局中,可以进行垂直或水平的排列子部件,并且各个小部件可以不必相同,排列的方向由orientation属性进行指定。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.graphics import Rectangle,Color
 
class StackLayoutWidget(StackLayout):
    def __init__(self,**kwargs):
        super(StackLayoutWidget, self).__init__(**kwargs)
 
        with self.canvas:
            Color(1,1,1,1)
            self.rect=Rectangle(pos=self.pos,size=self.size)
            self.bind(pos=self.update_rect,size=self.update_rect)
 
        #遍历添加按钮
        for i in range(25):
            btn=Button(text=str(i),width=40+i*5,size_hint=(None,0.15))
            self.add_widget(btn)
 
    def update_rect(self,*args):
        self.rect.pos=self.pos
        self.rect.size=self.size
 
class StackApp(App):
    def build(self):
        return StackLayoutWidget()
 
if __name__ =="__main__":
    StackApp().run()

以上每种布局都有代码示例,多对代码进行调试修改,将会更有心得。

因有同学问到我的kivy学习资料里支持中文的方法是怎么解决的,我将解决中文的方法链接贴在这里,大家去照着做就可以了,很简单点击这个链接进入:kivy全局中文支持最简单的解决方法

posted @ 2021-08-09 23:07  michaelxguo  阅读(1402)  评论(0编辑  收藏  举报