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全局中文支持最简单的解决方法。