2023年8月11日 星期五

Kivy UIX篇 widget篇 widget類 method篇 講解

若尚未看過Kivy UIX篇 widget篇 widget類  attribute篇 講解,建議看完之後對widget有一定了解在看這篇喔

根據官網widget類繼承自kivy.uix.widget.WidgetBase

在此篇教學中,我們使用Label來做為widget的示範(因為Label沒有過多雜質)

1.add_widget(widget, index=0, canvas=None):我們可以在widget物件中加入widget物件當作子物件

首先在main.py中寫下程式碼:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.uix.label import Label


class MyLayout(FloatLayout):
    a1 = ObjectProperty(None)
    num = NumericProperty()

    def btn(self):
        self.a1.add_widget(Label(text='{}'.format(self.num),
                                 pos=[self.num*10,self.num*10]))
        self.num = self.num+1


class Myapp(App):

    def build(self):
        return MyLayout()


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

以上程式碼代表

(1)a1 = ObjectProperty(None)代表a1為ObjectProperty物件

(2)num = NumericProperty()代表num為NumericProperty物件

(以上兩者為"kivy屬性",關於"kivy屬性"的介紹請參考property篇)

(3)定義一個函數btn

(4)self.a1.add_widget(Label(text='{}'.format(self.num), pos=[self.num*10,self.num*10]))代表變數label(我知道這邊說'變數'label對於學過python的人來說可能很怪,但這邊只是因為比較好表達)引用add_widget()方法,第一個參數為Label物件,而且這個Label物件的text參數為self.num,pos參數為[self.num*10,self.num*10],下一行程式碼為self.num = self.num+1,我們可以想像每當btn函數被呼叫,self.num都會改變

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

<MyLayout>:
    a1: b1

    Label:
        id: b1
        text: 'A1'
        on_touch_down: root.btn()

以上程式碼我們將main.py中的Label的id設為b1,在main.py中a1與my.kv中的b1連結。我們在Label中增加on_touch_down: root.btn()代表當我按下此Label時執行btn函數。

執行結果如下:

2.remove_widget(widget):將widget物件中的'一個'子物件移除

首先在main.py中寫下程式碼:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.uix.label import Label


class MyLayout(FloatLayout):
    a1 = ObjectProperty(None)
    num = NumericProperty()

    def btn1(self):
        self.a1.add_widget(Label(text='{}'.format(self.num), 
                                 pos=[self.num*10,self.num*10]))
        self.num = self.num+1

    def btn2(self):
        if self.a1.children:
            for child in self.a1.children[:3]: #此處可調整要移除幾個widget子物件
                self.a1.remove_widget(child)


class Myapp(App):

    def build(self):
        return MyLayout()


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

與add_widget例子相比,此例多加了函數btn2,這個函數的內容為:如果a1內存在子物件,則利用for迴圈迭代子物件列表,將子物件'一個一個'移除。

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

<MyLayout>:
    a1: b1

    Label:
        id: b1
        pos_hint: {'x':.1,'y':.1}
        size_hint: None, None
        size: 200,200
        text: 'A1'
        on_touch_down: root.btn1()
        
    Button:
        pos_hint: {'x':.5,'y':.5}
        size_hint: None, None
        size: 200,200
        text: 'press me'
        on_press: root.btn2()

與add_widget例子相比,在my.kv中多加了Button並讓他可以實現btn2函數(更多Button的用法請參考)

執行結果如下:

3.clear_widgets(children=None):將widget物件中的'全部'子物件移除

首先在main.py中寫下程式碼:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.uix.label import Label


class MyLayout(FloatLayout):
    a1 = ObjectProperty(None)
    num = NumericProperty()

    def btn1(self):
        self.a1.add_widget(Label(text='{}'.format(self.num), 
                                 pos=[self.num*10,self.num*10]))
        self.num = self.num+1

    def btn2(self):
        if self.a1.children:
                self.a1.clear_widgets()


class Myapp(App):

    def build(self):
        return MyLayout()


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

與remove_widget例子中的btn2相比,此例中在呼叫clear_widgets()方法時沒有使用到迭代

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

<MyLayout>:
    a1: b1

    Label:
        id: b1
        pos_hint: {'x':.1,'y':.1}
        size_hint: None, None
        size: 200,200
        text: 'A1'
        on_touch_down: root.btn1()
        
    Button:
        pos_hint: {'x':.5,'y':.5}
        size_hint: None, None
        size: 200,200
        text: 'press me'
        on_press: root.btn2()

此my.kv程式碼與remove_widget例子中的my.kv程式碼相同

執行結果如下:

4.collide_point(x, y):判斷(x, y)座標是否在widget物件內(注意:此處不代表作用範圍)

首先在main.py中寫下程式碼:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.uix.label import Label


class MyLayout(FloatLayout):
    a1 = ObjectProperty(None)
    num = NumericProperty()

    def btn1(self):
        print(self.a1.collide_point(500, 500)) #判斷(500, 500)是否在a1內


class Myapp(App):

    def build(self):
        return MyLayout()


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

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

<MyLayout>:
    a1: b1

    Label:
        id: b1
        text: 'A1'
        pos_hint: {'x':.1,'y':.1}
        size_hint: None, None
        size: 200,200

    Button:
        pos_hint: {'x':.5,'y':.5}
        size_hint: None, None
        size: 200,200
        text: 'press me'
        on_press: root.btn1()

執行結果如下:

5.collide_widget(wid):判斷wid是否在widget物件內(注意:此處不代表作用範圍)

首先在main.py中寫下程式碼:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.uix.label import Label


class MyLayout(FloatLayout):
    a1 = ObjectProperty(None)
    a2 = ObjectProperty(None)

    def btn1(self):
        print(self.a1.collide_widget(self.a2)) #判斷a2是否在widget物件內

class Myapp(App):

    def build(self):
        return MyLayout()


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

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

<MyLayout>:

    a1: b1
    a2: b2
    
    Label:
        id: b1
        text: 'A1'
        pos_hint: {'x':.1,'y':.1}
        size_hint: None, None
        size: 200,200

    Label:
        id: b2
        text: 'A2'
        #可以調整pos_hint來觀察print(self.a1.collide_widget(self.a2))的變化
        pos_hint: {'x':.2,'y':.8} 
        size_hint: None, None
        size: 200,200

    Button:
        pos_hint: {'x':.5,'y':.5}
        size_hint: None, None
        size: 200,200
        text: 'press me'
        on_press: root.btn1()

執行結果如下:

沒有留言:

張貼留言

精選文章

Kivy UIX篇 widget篇 TabbedPanel類 event篇 講解