2023年7月22日 星期六

Kivy UIX篇 layout篇 BoxLayout類 講解

簡述

根據官方解釋:

BoxLayout arranges children in a vertical or horizontal box.

意思是 BoxLayout 會以垂直或水平方向來排列子物件。

示意圖如下:

基本範例

首先在main.py中寫上起手式:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout


class MyLayout(BoxLayout):
    pass


class Myapp(App):

    def build(self):
        return MyLayout()


if __name__ == '__main__':
    Myapp().run()
    

在以上程式碼中,我讓MyLayout類繼承BoxLayout類,使得在my.kv中的<MyLayout>:可以繼承BoxLayout類的特性。

在my.kv中寫上此段程式碼:

<MyLayout>:

    spacing: 20 #物件之間的間隔,越大代表間隔越大,所以可以看到的背景面積越大
    orientation: 'vertical' #可根據需求調正為horizontal

    # 添加背景顏色(此段只是拿來呈現背景,後面會有更詳細的解說)
    canvas:
        Color:
            rgb: [.112, .358, .132]
        Rectangle:
            pos: self.pos
            size: self.size
    
    # 添加Button物件 (此段只是拿來呈現Button的位置,後面會有更詳細的解說)
    Button:
        text: 'Hello'

    Button:
        text: 'World'

    Button:
        text: 'How are you'

執行結果如下:

BoxLayout使用技巧

1.pos_hint的作用範圍,具體取決於方向:

(1)如果方向是垂直的(orientation: 'vertical'):將使用 x、right 和 center_x。

(2)如果方向是水平的(orientation: 'horizontal'):將使用 y、top 和 center_y。

上面看似難懂的敘述,我們用實例來說明

在my.kv中寫上此段程式碼:

<MyLayout>:

    spacing: 20 
    orientation: 'vertical' 

    canvas:
        Color:
            rgb: [.112, .358, .132]

        Rectangle:
            pos: self.pos
            size: self.size

    Button:
        text: 'Hello'

    Button:
        text: 'World'
        size_hint: None,None
        #此行程式碼代表'World'Button的常與寬皆設為200,我們將按鈕縮小以利示範
        size: 200,200
        #此行程式碼代表'World'Button的右邊將貼其整個Layout的0.2(後面會有更詳細的解說)
        pos_hint: {'right': 0.2}

    Button:
        text: 'How are you'

執行結果:

我們修改程式碼如下:

<MyLayout>:

    spacing: 20 
    orientation: 'vertical' 

    canvas:
        Color:
            rgb: [.112, .358, .132]

        Rectangle:
            pos: self.pos
            size: self.size

    Button:
        text: 'Hello'

    Button:
        text: 'World'
        size_hint: None,None
        size: 200,200
        #修改此行程式碼為0.8,代表'World'Button的右邊將貼其整個Layout的0.8
        pos_hint: {'right': 0.8}

    Button:
        text: 'How are you'

執行結果如下:

我們再修改程式碼如下:

<MyLayout>:

    spacing: 20 
    orientation: 'vertical' 

    canvas:
        Color:
            rgb: [.112, .358, .132]

        Rectangle:
            pos: self.pos
            size: self.size

    Button:
        text: 'Hello'

    Button:
        text: 'World'
        size_hint: None,None
        size: 200,200
        #修改此行程式碼,代表'World'Button的上面將貼其整個Layout的0.8
        pos_hint: {'top': 0.8}

    Button:
        text: 'How are you'

執行結果:

會發現最後一個執行結果不如預期,原因是因為當我們在添加物件到BoxLayout時,此物件的垂直長度已經決定此物件可以放置的垂直範圍,但此物件的水平長度並沒有決定此物件可以放置的水平範圍(聽起來很拗口,直接上圖!!!)

所以如果我將物件的垂直長度變小,則可放置的垂直範圍(H)變小,反之亦然;
        如果我將物件的水平長度變小,則可放置的水平範圍(W)不變,反之亦然。

此例的orientation為'vertical',各位可以思考若orientation為'horizontal'時結果為何?

2.若使用size_hint參數來調整子物件大小,則決定長度的不再是視窗的比例,計算方式為扣除宣告絕對長度的字物件的長度後,剩下的長度再依宣告的size_hint按比例分配。(看範例比較好懂)

在my.kv中寫上此段程式碼:

<MyLayout>:

    orientation: 'vertical'

    canvas:
        Color:
            rgb: [.112, .358, .132]

        Rectangle:
            pos: self.pos
            size: self.size

    Button:
        text: 'A1'
        size_hint: None, None
        size: 100,400

    Button:
        text: 'B2'
        size_hint: .1, .5

    Button:
        text: 'C3'
        size_hint: .1, .5

執行結果如下:

A1 Button、B2 Button、C3 Button的垂直長度由以下方式決定:

A1:400px

B2與C3:視窗垂直長度扣除400px後的剩餘垂直長度B2佔0.5、C3佔0.5

沒有留言:

張貼留言

精選文章

Kivy UIX篇 widget篇 TabbedPanel類 event篇 講解