Hướng dẫn build app with python - xây dựng ứng dụng với python



Các khóa học qua video:
Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript
Hướng dẫn build app with python - xây dựng ứng dụng với python

Mục lục bài viết:

  • Tìm hiểu về framework Kivy
  • Cài đặt Kivy
  • Làm việc với các widget Kivy
    • Chạy chương trình "Hello, Kivy!"
    • Hiển thị hình ảnh
  • Bố trí giao diện người dùng
  • Thêm sự kiện
  • Sử dụng ngôn ngữ KV
  • Tạo ứng dụng Kivy
  • Đóng gói ứng dụng của bạn cho Android
  • Đóng gói ứng dụng của bạn cho iOS
  • Đóng gói ứng dụng của bạn cho Windows
  • Đóng gói ứng dụng của bạn cho macOS
  • Phần kết luận
  • Đọc thêm

Ngày nay, các nhà phát triển rất có thể đang làm việc trên một ứng dụng web hoặc di động. Python không có khả năng phát triển di động tích hợp, nhưng có những gói bạn có thể sử dụng để tạo các ứng dụng di động như Kivy, PyQt hoặc thậm chí là thư viện Toga của Beeware.

Các thư viện này đều là những thư viện chủ đạo để phát triển ứng dụng di động bằng Python. Tuy nhiên, bạn sẽ thấy một số lợi ích nếu chọn tạo ứng dụng di động với Kivy. Ứng dụng của bạn không chỉ trông giống nhau trên tất cả các nền tảng mà còn không cần phải biên dịch mã của mình sau mỗi lần thay đổi. Hơn nữa, bạn sẽ có thể sử dụng cú pháp rõ ràng của Python để xây dựng các ứng dụng của mình.

Trong bài viết này, bạn sẽ học cách:

  • Làm việc với các widget Kivy
  • Bố trí giao diện người dùng
  • Thêm sự kiện
  • Sử dụng ngôn ngữ KV
  • Tạo ứng dụng Kivy
  • Đóng gói ứng dụng của bạn cho Android

Đóng gói ứng dụng của bạn cho iOS

Đóng gói ứng dụng của bạn cho Windows

Đóng gói ứng dụng của bạn cho macOS

Phần kết luận

Đọc thêm

Cài đặt Kivy

Làm việc với các widget Kivy

Chạy chương trình "Hello, Kivy!"

Hiển thị hình ảnh

Bố trí giao diện người dùng

Thêm sự kiện

Sử dụng ngôn ngữ KV

Tạo ứng dụng Kivy

Đóng gói ứng dụng của bạn cho Android

Đóng gói ứng dụng của bạn cho iOS

Đóng gói ứng dụng của bạn cho Windows

Đóng gói ứng dụng của bạn cho macOS

Phần kết luận

Đọc thêm

Chạy chương trình "Hello, Kivy!"

Hiển thị hình ảnh

from kivy.app import App
from kivy.uix.label import Label

class MainApp(App):
    def build(self):
        label = Label(text='Hello from Kivy',
                      size_hint=(.5, .5),
                      pos_hint={'center_x': .5, 'center_y': .5})

        return label

if __name__ == '__main__':
    app = MainApp()
    app.run()

Bố trí giao diện người dùng

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
9 cho Kivy biết tỷ lệ sử dụng khi tạo tiện ích con. Nó có hai số:

  1. Số đầu tiên là 
    from kivy.app import App
    from kivy.uix.button import Button
    
    class MainApp(App):
      def build(self):
        button = Button(text='Hello from Kivy',
                        size_hint=(.5, .5),
                        pos_hint={'center_x': .5, 'center_y': .5})
        button.bind(on_press=self.on_press_button)
    
        return button
    
      def on_press_button(self, obj):
        print('Bạn đã nhấn vào nút lệnh!', obj)
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    2 gợi ý về kích thước và đề cập đến chiều rộng của điều khiển.
  2. Số thứ hai là 
    from kivy.app import App
    from kivy.uix.button import Button
    
    class MainApp(App):
      def build(self):
        button = Button(text='Hello from Kivy',
                        size_hint=(.5, .5),
                        pos_hint={'center_x': .5, 'center_y': .5})
        button.bind(on_press=self.on_press_button)
    
        return button
    
      def on_press_button(self, obj):
        print('Bạn đã nhấn vào nút lệnh!', obj)
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    3 gợi ý kích thước và đề cập đến chiều cao của điều khiển.

Cả hai số này đều có thể nằm trong khoảng từ 0 đến 1. Giá trị mặc định cho cả hai gợi ý là 1. Bạn cũng có thể sử dụng 

from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
0 để định vị tiện ích con. Trong khối mã ở trên, bạn yêu cầu Kivy căn giữa tiện ích con trên trục x và y.

Để làm cho ứng dụng chạy, bạn khởi tạo lớp 

from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
5 của mình và sau đó gọi 
from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
6. Khi làm như vậy, bạn sẽ thấy thông tin sau trên màn hình của mình:

Kivy cũng xuất ra rất nhiều văn bản để 

from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
7:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

[INFO   ] [Logger      ] Record log in C:\Users\LongDT\.kivy\logs\kivy_21-04-16_38.txt[INFO   ] [deps        ] Successfully imported "kivy_deps.angle" 0.3.0[INFO   ] [deps        ] Successfully imported "kivy_deps.glew" 0.3.0[INFO   ] [deps        ] Successfully imported "kivy_deps.sdl2" 0.3.1[INFO   ] [Kivy        ] v2.0.0[INFO   ] [Kivy        ] Installed at "C:\Users\LongDT\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\__init__.py"[INFO   ] [Python      ] v3.9.3 (tags/v3.9.3:e723086, Apr  2 2021, 11:35:20) [MSC v.1928 64 bit (AMD64)][INFO   ] [Python      ] Interpreter at "C:\Users\LongDT\AppData\Local\Programs\Python\Python39\python.exe"[INFO   ] [Factory     ] 186 symbols loaded[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)[INFO   ] [Text        ] Provider: sdl2[INFO   ] [Window      ] Provider: sdl2[INFO   ] [GL          ] Using the "OpenGL" graphics system[INFO   ] [GL          ] GLEW initialization succeeded[INFO   ] [GL          ] Backend used [INFO   ] [GL          ] OpenGL version [INFO   ] [GL          ] OpenGL vendor [INFO   ] [GL          ] OpenGL renderer [INFO   ] [GL          ] OpenGL parsed version: 4, 3[INFO   ] [GL          ] Shading version [INFO   ] [GL          ] Texture max size [INFO   ] [GL          ] Texture max units [INFO   ] [Window      ] auto add sdl2 input provider[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked[INFO   ] [Base        ] Start application main loop[INFO   ] [GL          ] NPOT texture support is available[INFO   ] [Base        ] Leaving application in progress...
[INFO   ] [deps        ] Successfully imported "kivy_deps.angle" 0.3.0
[INFO   ] [deps        ] Successfully imported "kivy_deps.glew" 0.3.0
[INFO   ] [deps        ] Successfully imported "kivy_deps.sdl2" 0.3.1
[INFO   ] [Kivy        ] v2.0.0
[INFO   ] [Kivy        ] Installed at "C:\Users\LongDT\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\__init__.py"
[INFO   ] [Python      ] v3.9.3 (tags/v3.9.3:e723086, Apr  2 2021, 11:35:20) [MSC v.1928 64 bit (AMD64)]
[INFO   ] [Python      ] Interpreter at "C:\Users\LongDT\AppData\Local\Programs\Python\Python39\python.exe"
[INFO   ] [Factory     ] 186 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [Window      ] Provider: sdl2
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] GLEW initialization succeeded
[INFO   ] [GL          ] Backend used
[INFO   ] [GL          ] OpenGL version
[INFO   ] [GL          ] OpenGL vendor
[INFO   ] [GL          ] OpenGL renderer
[INFO   ] [GL          ] OpenGL parsed version: 4, 3
[INFO   ] [GL          ] Shading version
[INFO   ] [GL          ] Texture max size <16384>
[INFO   ] [GL          ] Texture max units <32>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [Base        ] Start application main loop
[INFO   ] [GL          ] NPOT texture support is available
[INFO   ] [Base        ] Leaving application in progress...

Điều này rất hữu ích để gỡ lỗi ứng dụng của bạn.

Hiển thị hình ảnh

Kivy có một vài widget liên quan đến hình ảnh khác nhau để bạn lựa chọn. Bạn có thể sử dụng 

from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
9 để tải hình ảnh cục bộ từ ổ cứng của mình hoặc 
from kivy.app import App
from kivy.uix.button import Button

class ButtonApp(App):
    def build(self):
        return Button()

    def on_press_button(self):
        print('You pressed the button!')

if __name__ == '__main__':
    app = ButtonApp()
    app.run()
0 để tải hình ảnh từ một URL. Đối với ví dụ này, ta sẽ sử dụng lớp chuẩn là 
from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
9:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()

Trong mã này, bạn nhập 

from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
9từ 
from kivy.app import App
from kivy.uix.button import Button

class ButtonApp(App):
    def build(self):
        return Button()

    def on_press_button(self):
        print('You pressed the button!')

if __name__ == '__main__':
    app = ButtonApp()
    app.run()
4gói phụ. Các 
from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
9lớp mất rất nhiều thông số khác nhau, nhưng một trong những mà bạn muốn sử dụng là 
from kivy.app import App
from kivy.uix.button import Button

class ButtonApp(App):
    def build(self):
        return Button()

    def on_press_button(self):
        print('You pressed the button!')

if __name__ == '__main__':
    app = ButtonApp()
    app.run()
6. Điều này cho Kivy biết hình ảnh nào cần tải. Tại đây, bạn chuyển một đường dẫn đầy đủ điều kiện đến hình ảnh. Phần còn lại của mã giống như những gì bạn đã thấy trong ví dụ trước.

Khi bạn chạy mã này, bạn sẽ thấy một cái gì đó như sau:

Bây giờ ta sẽ học cách thêm và sắp xếp nhiều widget trong ứng dụng của mình.

Bố trí giao diện người dùng

Mỗi khung GUI mà bạn sử dụng có phương pháp sắp xếp widget riêng. Ví dụ: trong wxPython, bạn sẽ sử dụng sizers, trong khi trong Tkinter, bạn sử dụng trình quản lý bố cục hoặc hình học. Với Kivy, bạn sẽ sử dụng các Layout (Bố cục). Có một số loại Bố cục khác nhau mà bạn có thể sử dụng như sau:

  • from kivy.app import App
    from kivy.uix.button import Button
    
    class ButtonApp(App):
        def build(self):
            return Button()
    
        def on_press_button(self):
            print('You pressed the button!')
    
    if __name__ == '__main__':
        app = ButtonApp()
        app.run()
    7
  • from kivy.app import App
    from kivy.uix.button import Button
    
    class ButtonApp(App):
        def build(self):
            return Button()
    
        def on_press_button(self):
            print('You pressed the button!')
    
    if __name__ == '__main__':
        app = ButtonApp()
        app.run()
    8
  • from kivy.app import App
    from kivy.uix.button import Button
    
    class ButtonApp(App):
        def build(self):
            return Button()
    
        def on_press_button(self):
            print('You pressed the button!')
    
    if __name__ == '__main__':
        app = ButtonApp()
        app.run()
    9

Dưới đây là ví dụ với 

from kivy.app import App
from kivy.uix.button import Button

class ButtonApp(App):
    def build(self):
        return Button()

    def on_press_button(self):
        print('You pressed the button!')

if __name__ == '__main__':
    app = ButtonApp()
    app.run()
7:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()

Trong ví dụ trên, ta import 

from kivy.app import App
from kivy.uix.button import Button

class ButtonApp(App):
    def build(self):
        return Button()

    def on_press_button(self):
        print('You pressed the button!')

if __name__ == '__main__':
    app = ButtonApp()
    app.run()
7 từ 
 1
3 và khởi tạo nó. Sau đó, ta tạo một danh sách các màu. Cuối cùng, ta dùng vòng lặp lặp 5 lần, mỗi lần lặp sẽ tạo một nút 
 1
4. Để làm cho mọi thứ vui vẻ hơn một chút, bạn đặt thuộc tính 
 1
5 của nút thành một màu ngẫu nhiên. Sau đó, bạn thêm nút vào bố cục của mình bằng lệnh 
 1
6.

Khi bạn chạy mã trên thì kết quả sẽ có dạng như ảnh dưới đây:

Có 5 nút màu ngẫu nhiên, một nút cho mỗi lần lặp lại vòng lặp for của bạn.

Khi bạn tạo một bố cục, có một số đối số bạn nên biết:

  •  1
    7: Bạn có thể chỉ định 
     1
    7in theo đơn vị pixel giữa bố cục và con của nó theo một trong ba cách:
    1. Danh sách bốn đối số: [
       1
      9, 
       1from kivy.app import App
       2from kivy.uix.boxlayout import BoxLayout
       3from kivy.uix.button import Button
       4from kivy.uix.textinput import TextInput
       5
       6class MainApp(App):
       7    def build(self):
       8        self.operators = ["/", "*", "+", "-"]
       9        self.last_was_operator = None
      10        self.last_button = None
      11        main_layout = BoxLayout(orientation="vertical")
      12        self.solution = TextInput(
      13            multiline=False, readonly=True, halign="right", font_size=55
      14        )
      15        main_layout.add_widget(self.solution)
      16        buttons = [
      17            ["7", "8", "9", "/"],
      18            ["4", "5", "6", "*"],
      19            ["1", "2", "3", "-"],
      20            [".", "0", "C", "+"],
      21        ]
      22        for row in buttons:
      23            h_layout = BoxLayout()
      24            for label in row:
      25                button = Button(
      26                    text=label,
      27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
      28                )
      29                button.bind(on_press=self.on_button_press)
      30                h_layout.add_widget(button)
      31            main_layout.add_widget(h_layout)
      32
      33        equals_button = Button(
      34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
      35        )
      36        equals_button.bind(on_press=self.on_solution)
      37        main_layout.add_widget(equals_button)
      38
      39        return main_layout
      40
      0, 
       1from kivy.app import App
       2from kivy.uix.boxlayout import BoxLayout
       3from kivy.uix.button import Button
       4from kivy.uix.textinput import TextInput
       5
       6class MainApp(App):
       7    def build(self):
       8        self.operators = ["/", "*", "+", "-"]
       9        self.last_was_operator = None
      10        self.last_button = None
      11        main_layout = BoxLayout(orientation="vertical")
      12        self.solution = TextInput(
      13            multiline=False, readonly=True, halign="right", font_size=55
      14        )
      15        main_layout.add_widget(self.solution)
      16        buttons = [
      17            ["7", "8", "9", "/"],
      18            ["4", "5", "6", "*"],
      19            ["1", "2", "3", "-"],
      20            [".", "0", "C", "+"],
      21        ]
      22        for row in buttons:
      23            h_layout = BoxLayout()
      24            for label in row:
      25                button = Button(
      26                    text=label,
      27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
      28                )
      29                button.bind(on_press=self.on_button_press)
      30                h_layout.add_widget(button)
      31            main_layout.add_widget(h_layout)
      32
      33        equals_button = Button(
      34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
      35        )
      36        equals_button.bind(on_press=self.on_solution)
      37        main_layout.add_widget(equals_button)
      38
      39        return main_layout
      40
      1, 
       1from kivy.app import App
       2from kivy.uix.boxlayout import BoxLayout
       3from kivy.uix.button import Button
       4from kivy.uix.textinput import TextInput
       5
       6class MainApp(App):
       7    def build(self):
       8        self.operators = ["/", "*", "+", "-"]
       9        self.last_was_operator = None
      10        self.last_button = None
      11        main_layout = BoxLayout(orientation="vertical")
      12        self.solution = TextInput(
      13            multiline=False, readonly=True, halign="right", font_size=55
      14        )
      15        main_layout.add_widget(self.solution)
      16        buttons = [
      17            ["7", "8", "9", "/"],
      18            ["4", "5", "6", "*"],
      19            ["1", "2", "3", "-"],
      20            [".", "0", "C", "+"],
      21        ]
      22        for row in buttons:
      23            h_layout = BoxLayout()
      24            for label in row:
      25                button = Button(
      26                    text=label,
      27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
      28                )
      29                button.bind(on_press=self.on_button_press)
      30                h_layout.add_widget(button)
      31            main_layout.add_widget(h_layout)
      32
      33        equals_button = Button(
      34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
      35        )
      36        equals_button.bind(on_press=self.on_solution)
      37        main_layout.add_widget(equals_button)
      38
      39        return main_layout
      40
      2]
    2. Danh sách hai đối số: [
       1from kivy.app import App
       2from kivy.uix.boxlayout import BoxLayout
       3from kivy.uix.button import Button
       4from kivy.uix.textinput import TextInput
       5
       6class MainApp(App):
       7    def build(self):
       8        self.operators = ["/", "*", "+", "-"]
       9        self.last_was_operator = None
      10        self.last_button = None
      11        main_layout = BoxLayout(orientation="vertical")
      12        self.solution = TextInput(
      13            multiline=False, readonly=True, halign="right", font_size=55
      14        )
      15        main_layout.add_widget(self.solution)
      16        buttons = [
      17            ["7", "8", "9", "/"],
      18            ["4", "5", "6", "*"],
      19            ["1", "2", "3", "-"],
      20            [".", "0", "C", "+"],
      21        ]
      22        for row in buttons:
      23            h_layout = BoxLayout()
      24            for label in row:
      25                button = Button(
      26                    text=label,
      27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
      28                )
      29                button.bind(on_press=self.on_button_press)
      30                h_layout.add_widget(button)
      31            main_layout.add_widget(h_layout)
      32
      33        equals_button = Button(
      34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
      35        )
      36        equals_button.bind(on_press=self.on_solution)
      37        main_layout.add_widget(equals_button)
      38
      39        return main_layout
      40
      3, 
       1from kivy.app import App
       2from kivy.uix.boxlayout import BoxLayout
       3from kivy.uix.button import Button
       4from kivy.uix.textinput import TextInput
       5
       6class MainApp(App):
       7    def build(self):
       8        self.operators = ["/", "*", "+", "-"]
       9        self.last_was_operator = None
      10        self.last_button = None
      11        main_layout = BoxLayout(orientation="vertical")
      12        self.solution = TextInput(
      13            multiline=False, readonly=True, halign="right", font_size=55
      14        )
      15        main_layout.add_widget(self.solution)
      16        buttons = [
      17            ["7", "8", "9", "/"],
      18            ["4", "5", "6", "*"],
      19            ["1", "2", "3", "-"],
      20            [".", "0", "C", "+"],
      21        ]
      22        for row in buttons:
      23            h_layout = BoxLayout()
      24            for label in row:
      25                button = Button(
      26                    text=label,
      27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
      28                )
      29                button.bind(on_press=self.on_button_press)
      30                h_layout.add_widget(button)
      31            main_layout.add_widget(h_layout)
      32
      33        equals_button = Button(
      34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
      35        )
      36        equals_button.bind(on_press=self.on_solution)
      37        main_layout.add_widget(equals_button)
      38
      39        return main_layout
      40
      4]
    3. Danh sách một đối số: 
       1from kivy.app import App
       2from kivy.uix.boxlayout import BoxLayout
       3from kivy.uix.button import Button
       4from kivy.uix.textinput import TextInput
       5
       6class MainApp(App):
       7    def build(self):
       8        self.operators = ["/", "*", "+", "-"]
       9        self.last_was_operator = None
      10        self.last_button = None
      11        main_layout = BoxLayout(orientation="vertical")
      12        self.solution = TextInput(
      13            multiline=False, readonly=True, halign="right", font_size=55
      14        )
      15        main_layout.add_widget(self.solution)
      16        buttons = [
      17            ["7", "8", "9", "/"],
      18            ["4", "5", "6", "*"],
      19            ["1", "2", "3", "-"],
      20            [".", "0", "C", "+"],
      21        ]
      22        for row in buttons:
      23            h_layout = BoxLayout()
      24            for label in row:
      25                button = Button(
      26                    text=label,
      27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
      28                )
      29                button.bind(on_press=self.on_button_press)
      30                h_layout.add_widget(button)
      31            main_layout.add_widget(h_layout)
      32
      33        equals_button = Button(
      34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
      35        )
      36        equals_button.bind(on_press=self.on_solution)
      37        main_layout.add_widget(equals_button)
      38
      39        return main_layout
      40
      5
  •  1from kivy.app import App
     2from kivy.uix.boxlayout import BoxLayout
     3from kivy.uix.button import Button
     4from kivy.uix.textinput import TextInput
     5
     6class MainApp(App):
     7    def build(self):
     8        self.operators = ["/", "*", "+", "-"]
     9        self.last_was_operator = None
    10        self.last_button = None
    11        main_layout = BoxLayout(orientation="vertical")
    12        self.solution = TextInput(
    13            multiline=False, readonly=True, halign="right", font_size=55
    14        )
    15        main_layout.add_widget(self.solution)
    16        buttons = [
    17            ["7", "8", "9", "/"],
    18            ["4", "5", "6", "*"],
    19            ["1", "2", "3", "-"],
    20            [".", "0", "C", "+"],
    21        ]
    22        for row in buttons:
    23            h_layout = BoxLayout()
    24            for label in row:
    25                button = Button(
    26                    text=label,
    27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
    28                )
    29                button.bind(on_press=self.on_button_press)
    30                h_layout.add_widget(button)
    31            main_layout.add_widget(h_layout)
    32
    33        equals_button = Button(
    34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
    35        )
    36        equals_button.bind(on_press=self.on_solution)
    37        main_layout.add_widget(equals_button)
    38
    39        return main_layout
    40
    6: Bạn có thể thêm khoảng cách giữa các widget con bằng đối số này.
  •  1from kivy.app import App
     2from kivy.uix.boxlayout import BoxLayout
     3from kivy.uix.button import Button
     4from kivy.uix.textinput import TextInput
     5
     6class MainApp(App):
     7    def build(self):
     8        self.operators = ["/", "*", "+", "-"]
     9        self.last_was_operator = None
    10        self.last_button = None
    11        main_layout = BoxLayout(orientation="vertical")
    12        self.solution = TextInput(
    13            multiline=False, readonly=True, halign="right", font_size=55
    14        )
    15        main_layout.add_widget(self.solution)
    16        buttons = [
    17            ["7", "8", "9", "/"],
    18            ["4", "5", "6", "*"],
    19            ["1", "2", "3", "-"],
    20            [".", "0", "C", "+"],
    21        ]
    22        for row in buttons:
    23            h_layout = BoxLayout()
    24            for label in row:
    25                button = Button(
    26                    text=label,
    27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
    28                )
    29                button.bind(on_press=self.on_button_press)
    30                h_layout.add_widget(button)
    31            main_layout.add_widget(h_layout)
    32
    33        equals_button = Button(
    34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
    35        )
    36        equals_button.bind(on_press=self.on_solution)
    37        main_layout.add_widget(equals_button)
    38
    39        return main_layout
    40
    7: Bạn có thể thay đổi mặc định 
     1from kivy.app import App
     2from kivy.uix.boxlayout import BoxLayout
     3from kivy.uix.button import Button
     4from kivy.uix.textinput import TextInput
     5
     6class MainApp(App):
     7    def build(self):
     8        self.operators = ["/", "*", "+", "-"]
     9        self.last_was_operator = None
    10        self.last_button = None
    11        main_layout = BoxLayout(orientation="vertical")
    12        self.solution = TextInput(
    13            multiline=False, readonly=True, halign="right", font_size=55
    14        )
    15        main_layout.add_widget(self.solution)
    16        buttons = [
    17            ["7", "8", "9", "/"],
    18            ["4", "5", "6", "*"],
    19            ["1", "2", "3", "-"],
    20            [".", "0", "C", "+"],
    21        ]
    22        for row in buttons:
    23            h_layout = BoxLayout()
    24            for label in row:
    25                button = Button(
    26                    text=label,
    27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
    28                )
    29                button.bind(on_press=self.on_button_press)
    30                h_layout.add_widget(button)
    31            main_layout.add_widget(h_layout)
    32
    33        equals_button = Button(
    34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
    35        )
    36        equals_button.bind(on_press=self.on_solution)
    37        main_layout.add_widget(equals_button)
    38
    39        return main_layout
    40
    7 của 
    from kivy.app import App
    from kivy.uix.button import Button
    
    class ButtonApp(App):
        def build(self):
            return Button()
    
        def on_press_button(self):
            print('You pressed the button!')
    
    if __name__ == '__main__':
        app = ButtonApp()
        app.run()
    7 từ ngang sang dọc.

Thêm sự kiện

Giống như hầu hết các bộ công cụ GUI, Kivy chủ yếu dựa trên sự kiện. Framework phản hồi các thao tác nhấn phím của người dùng, sự kiện chuột và sự kiện chạm. Kivy có khái niệm về Đồng hồ (Clock) mà bạn có thể sử dụng để lên lịch các lời gọi hàm trong một thời gian nào đó trong tương lai.

Kivy cũng có khái niệm về 

41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
0
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
1, nó hoạt động với 
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
2
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
3. Thuộc tính này giúp bạn kiểm tra xác thực. Chúng cũng cho phép bạn kích hoạt các sự kiện bất cứ khi nào tiện ích con thay đổi kích thước hoặc vị trí của nó.

Dưới đây là ví dụ về sự kiện nhấn nút:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()

Trong ví dụ trên, bạn gọi 

41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
5 và liên kết sự kiện 
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
6sự kiện với 
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
7. Phương thức này mặc nhiên nhận widget 
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
8, chính là đối tượng 
41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61
9. Cuối cùng, một thông báo sẽ được in ra 
from kivy.app import App
from kivy.uix.button import Button

class MainApp(App):
  def build(self):
    button = Button(text='Hello from Kivy',
                    size_hint=(.5, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    button.bind(on_press=self.on_press_button)

    return button

  def on_press_button(self, obj):
    print('Bạn đã nhấn vào nút lệnh!', obj)

if __name__ == '__main__':
  app = MainApp()
  app.run()
7 bất cứ khi nào người dùng nhấn vào nút button.

Sử dụng ngôn ngữ KV

Kivy cũng cung cấp một ngôn ngữ thiết kế gọi là KV mà bạn có thể sử dụng với các ứng dụng Kivy của mình. Ngôn ngữ KV cho phép bạn tách thiết kế giao diện của mình khỏi logic của ứng dụng. Điều này tuân theo nguyên tắc phân tách các mối quan tâm và là một phần của mô hình kiến ​​trúc Model-View-Controller. Bạn có thể cập nhật ví dụ trước để sử dụng ngôn ngữ KV:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.button import Button

class ButtonApp(App):
    def build(self):
        return Button()

    def on_press_button(self):
        print('You pressed the button!')

if __name__ == '__main__':
    app = ButtonApp()
    app.run()

Mã này thoạt nhìn có thể hơi kỳ quặc, vì nó tạo ra một mã 

62def on_solution(self, instance):
63    text = self.solution.text
64    if text:
65        solution = str(eval(self.solution.text))
66        self.solution.text = solution
67
2 mà không đặt bất kỳ thuộc tính nào của nó hoặc ràng buộc nó với bất kỳ sự kiện nào. Điều đang xảy ra ở đây là Kivy sẽ tự động tìm kiếm một tệp có cùng tên với lớp ở dạng chữ thường, không có phần 
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
5 của tên của lớp.

Trong trường hợp này, tên lớp là 

62def on_solution(self, instance):
63    text = self.solution.text
64    if text:
65        solution = str(eval(self.solution.text))
66        self.solution.text = solution
67
4, vì vậy Kivy sẽ tìm kiếm một tệp có tên 
62def on_solution(self, instance):
63    text = self.solution.text
64    if text:
65        solution = str(eval(self.solution.text))
66        self.solution.text = solution
67
5. Nếu tệp đó tồn tại và được định dạng đúng, thì Kivy sẽ sử dụng tệp đó để tải lên giao diện người dùng. Hãy tiếp tục và tạo tệp này và thêm mã sau:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

 1

Kết quả:

Giải thích:

  • Dòng 1 khớp với lệnh gọi 
    62def on_solution(self, instance):
    63    text = self.solution.text
    64    if text:
    65        solution = str(eval(self.solution.text))
    66        self.solution.text = solution
    67
    2 trong mã Python của bạn. Nó yêu cầu Kivy nhìn vào đối tượng khởi tạo để xác định nút.
  • Dòng 2 sẽ đặt 
    import kivy
    import random
    
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.boxlayout import BoxLayout
    
    red = [1, 0, 0, 1]
    green = [0, 1, 0, 1]
    blue = [0, 0, 1, 1]
    purple = [1, 0, 1, 1]
    
    class HBoxLayoutExample(App):
      def build(self):
        layout = BoxLayout(padding=10)
        colors = [red, green, blue, purple]
    
        for i in range(5):
          btn = Button(text="Button #%s" % (i + 1),
                       background_color=random.choice(colors)
                       )
    
          layout.add_widget(btn)
        return layout
    
    if __name__ == "__main__":
      app = HBoxLayoutExample()
      app.run()
    
    8 cho button.
  • Dòng 3 đặt chiều rộng và chiều cao với 
    import kivy
    import random
    
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.boxlayout import BoxLayout
    
    red = [1, 0, 0, 1]
    green = [0, 1, 0, 1]
    blue = [0, 0, 1, 1]
    purple = [1, 0, 1, 1]
    
    class HBoxLayoutExample(App):
      def build(self):
        layout = BoxLayout(padding=10)
        colors = [red, green, blue, purple]
    
        for i in range(5):
          btn = Button(text="Button #%s" % (i + 1),
                       background_color=random.choice(colors)
                       )
    
          layout.add_widget(btn)
        return layout
    
    if __name__ == "__main__":
      app = HBoxLayoutExample()
      app.run()
    
    9.
  • Dòng 4 đặt vị trí của nút với 
    from kivy.app import App
    from kivy.uix.button import Button
    
    class MainApp(App):
      def build(self):
        button = Button(text='Hello from Kivy',
                        size_hint=(.5, .5),
                        pos_hint={'center_x': .5, 'center_y': .5})
        button.bind(on_press=self.on_press_button)
    
        return button
    
      def on_press_button(self, obj):
        print('Bạn đã nhấn vào nút lệnh!', obj)
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    0.
  • Dòng 5 thiết lập trình xử lý sự kiện 
    41def on_button_press(self, instance):
    42    current = self.solution.text
    43    button_text = instance.text
    44
    45    if button_text == "C":
    46        # xóa text của solution
    47        self.solution.text = ""
    48    else:
    49        if current and (
    50            self.last_was_operator and button_text in self.operators):
    51            # không thêm hai phép toán liên tục
    52            return
    53        elif current == "" and button_text in self.operators:
    54            # ký tự đầu tiên không được là phép toán
    55            return
    56        else:
    57            new_text = current + button_text
    58            self.solution.text = new_text
    59    self.last_button = button_text
    60    self.last_was_operator = self.last_button in self.operators
    61
    
    6. Để cho Kivy biết trình xử lý sự kiện ở đâu, bạn sử dụng 
    $ pip install buildozer
    2. Ở đây, Kivy biết sẽ tìm trong lớp 
    62def on_solution(self, instance):
    63    text = self.solution.text
    64    if text:
    65        solution = str(eval(self.solution.text))
    66        self.solution.text = solution
    67
    4 phương thức có tên 
    $ pip install buildozer
    4.

Bạn có thể thiết lập tất cả các widget và bố cục của mình bên trong một hoặc nhiều tệp ngôn ngữ KV. Ngôn ngữ KV cũng hỗ trợ nhập các mô-đun Python trong KV, tạo các lớp động và hơn thế nữa. Để biết đầy đủ chi tiết, hãy xem hướng dẫn của Kivy về Ngôn ngữ KV.

Bây giờ bạn đã sẵn sàng để tạo một ứng dụng thực sự!

Tạo ứng dụng Kivy

Một trong những cách tốt nhất để học một kỹ năng mới là tạo ra thứ gì đó hữu ích. Với ý nghĩ đó, bạn sẽ sử dụng Kivy để tạo một máy tính hỗ trợ các hoạt động sau:

  • Phép cộng
  • Phép trừ
  • Phép nhân
  • Phép chia

Đối với ứng dụng này, bạn sẽ cần một loạt các nút trong một số loại bố cục. Bạn cũng sẽ cần một box phía đầu ứng dụng của mình để hiển thị cho phần tính toán và kết quả. Đây là bản phác thảo của máy tính của bạn:

Bây giờ bạn đã có mục tiêu cho giao diện người dùng, bạn có thể tiếp tục và viết mã Python:

 1from kivy.app import App
 2from kivy.uix.boxlayout import BoxLayout
 3from kivy.uix.button import Button
 4from kivy.uix.textinput import TextInput
 5
 6class MainApp(App):
 7    def build(self):
 8        self.operators = ["/", "*", "+", "-"]
 9        self.last_was_operator = None
10        self.last_button = None
11        main_layout = BoxLayout(orientation="vertical")
12        self.solution = TextInput(
13            multiline=False, readonly=True, halign="right", font_size=55
14        )
15        main_layout.add_widget(self.solution)
16        buttons = [
17            ["7", "8", "9", "/"],
18            ["4", "5", "6", "*"],
19            ["1", "2", "3", "-"],
20            [".", "0", "C", "+"],
21        ]
22        for row in buttons:
23            h_layout = BoxLayout()
24            for label in row:
25                button = Button(
26                    text=label,
27                    pos_hint={"center_x": 0.5, "center_y": 0.5},
28                )
29                button.bind(on_press=self.on_button_press)
30                h_layout.add_widget(button)
31            main_layout.add_widget(h_layout)
32
33        equals_button = Button(
34            text="=", pos_hint={"center_x": 0.5, "center_y": 0.5}
35        )
36        equals_button.bind(on_press=self.on_solution)
37        main_layout.add_widget(equals_button)
38
39        return main_layout
40

Giải thích:

  • Trong các dòng từ 8 đến 10: bạn tạo một danh sách (list) các phép toán (
    $ pip install buildozer
    5) và hai giá trị 
    $ pip install buildozer
    6 và 
    $ pip install buildozer
    7 sẽ sử dụng sau này.
  • Trong các dòng từ 11 đến 15, bạn tạo bố cục cấp cao nhất 
    $ pip install buildozer
    8 và thêm tiện ích 
    $ pip install buildozer
    9 chỉ đọc vào bố cục.
  • Trong các dòng từ 16 đến 21, bạn tạo một danh sách lồng nhau gồm các danh sách chứa hầu hết các 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    00 cho máy tính.
  • Trong dòng 22, bạn bắt đầu một vòng lặp for trên các 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    00. Đối với mỗi danh sách lồng nhau, bạn sẽ thực hiện như sau:
    • Trong dòng 23, bạn tạo một 
      from kivy.app import App
      from kivy.uix.button import Button
      
      class ButtonApp(App):
          def build(self):
              return Button()
      
          def on_press_button(self):
              print('You pressed the button!')
      
      if __name__ == '__main__':
          app = ButtonApp()
          app.run()
      7 với hướng nằm ngang.
    • Trong dòng 24, bạn bắt đầu một vòng lặp 
      from kivy.app import App
      from kivy.uix.image import Image
      
      class MainApp(App):
        def build(self):
          img = Image(source='icon_v1study.png',
                      size_hint=(1, .5),
                      pos_hint={'center_x': .5, 'center_y': .5})
      
          return img
      
      if __name__ == '__main__':
        app = MainApp()
        app.run()
      
      03 khác trên các mục trong danh sách lồng nhau.
    • Trong các dòng từ 25 đến 39, bạn tạo các nút cho hàng, liên kết chúng với một trình xử lý sự kiện và thêm các nút vào hàng ngang 
      from kivy.app import App
      from kivy.uix.button import Button
      
      class ButtonApp(App):
          def build(self):
              return Button()
      
          def on_press_button(self):
              print('You pressed the button!')
      
      if __name__ == '__main__':
          app = ButtonApp()
          app.run()
      7 từ dòng 23.
    • Trong dòng 31, bạn thêm bố cục này vào 
      $ pip install buildozer
      8.
  • Trong các dòng từ 33 đến 37, bạn tạo nút bằng (
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    06), liên kết nó với một trình xử lý sự kiện và thêm nó vào 
    $ pip install buildozer
    8.

Bước tiếp theo là ta tạo trình xử lý sự kiện 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
08 với đoạn mã như sau:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

41def on_button_press(self, instance):
42    current = self.solution.text
43    button_text = instance.text
44
45    if button_text == "C":
46        # xóa text của solution
47        self.solution.text = ""
48    else:
49        if current and (
50            self.last_was_operator and button_text in self.operators):
51            # không thêm hai phép toán liên tục
52            return
53        elif current == "" and button_text in self.operators:
54            # ký tự đầu tiên không được là phép toán
55            return
56        else:
57            new_text = current + button_text
58            self.solution.text = new_text
59    self.last_button = button_text
60    self.last_was_operator = self.last_button in self.operators
61

Hầu hết các widget trong ứng dụng của bạn sẽ gọi 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
10. Sau đây là một số giải thích:

  • Dòng 41 lấy đối số 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    11 để bạn có thể truy cập tiện ích con nào được gọi là hàm.
  • Dòng 42 và 43 trích xuất và lưu trữ giá trị của 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    12 và của nút 
    import kivy
    import random
    
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.boxlayout import BoxLayout
    
    red = [1, 0, 0, 1]
    green = [0, 1, 0, 1]
    blue = [0, 0, 1, 1]
    purple = [1, 0, 1, 1]
    
    class HBoxLayoutExample(App):
      def build(self):
        layout = BoxLayout(padding=10)
        colors = [red, green, blue, purple]
    
        for i in range(5):
          btn = Button(text="Button #%s" % (i + 1),
                       background_color=random.choice(colors)
                       )
    
          layout.add_widget(btn)
        return layout
    
    if __name__ == "__main__":
      app = HBoxLayoutExample()
      app.run()
    
    8.
  • Dòng 45 đến 47 kiểm tra xem nút nào đã được nhấn. Nếu người dùng nhấn 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    14, thì bạn sẽ xóa 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    12. Nếu không thì chuyển sang 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    16.
  • Dòng 49 kiểm tra xem solution có bất kỳ giá trị nào tồn tại từ trước hay không.
  • Dòng 50 đến 52 kiểm tra xem nút cuối cùng được nhấn có phải là nút phép toán hay không. Nếu phải thì 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    12 sẽ không được cập nhật. Điều này là để ngăn người dùng đưa vào hai phép toán liên tiếp. Ví dụ như 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    18 là không hợp lệ.
  • Các dòng từ 53 đến 55 kiểm tra xem ký tự đầu tiên có phải là toán tử hay không. Nếu đúng thì 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    12 sẽ không được cập nhật vì giá trị đầu tiên không được là giá trị toán tử.
  • Các dòng từ 56 đến 58 là mệnh đề 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    16. Nếu không có điều kiện nào trước đó được đáp ứng thì sẽ cập nhật 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    12.
  • Dòng 59 đặt 
    $ pip install buildozer
    7 thành nhãn của nút cuối cùng được nhấn.
  • Dòng 60 đặt 
    $ pip install buildozer
    6 thành 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    24 hoặc 
    from kivy.app import App
    from kivy.uix.image import Image
    
    class MainApp(App):
      def build(self):
        img = Image(source='icon_v1study.png',
                    size_hint=(1, .5),
                    pos_hint={'center_x': .5, 'center_y': .5})
    
        return img
    
    if __name__ == '__main__':
      app = MainApp()
      app.run()
    
    25 tùy thuộc vào việc nó có phải là một ký tự toán tử hay không.

Sau đây là phần cuối của chương trình, phương thức 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
26:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

62def on_solution(self, instance):
63    text = self.solution.text
64    if text:
65        solution = str(eval(self.solution.text))
66        self.solution.text = solution
67

Một lần nữa, bạn lấy văn bản hiện tại 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
12 và sử dụng hàm eval() để thực thi nó. Nếu người dùng đã tạo một biểu thức chẳng hạn như 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
29, thì 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
30 sẽ chạy mã của bạn và trả về kết quả. Cuối cùng, bạn đặt kết quả là giá trị mới cho tiện ích con 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
12.

Lưu ý: eval() hơi nguy hiểm vì nó có thể chạy mã tùy ý. Hầu hết các nhà phát triển tránh sử dụng nó vì thực tế này. Tuy nhiên, vì bạn chỉ cho phép số nguyên, toán tử và dấu chấm làm đầu vào eval(), nên bạn có thể sử dụng an toàn trong tình huống này.

Khi bạn chạy code trên, ứng dụng của bạn sẽ trông giống như thế này trên máy tính để bàn (desktop):

Đóng gói ứng dụng của bạn cho Android

Bây giờ bạn bạn có thể chia sẻ code với những người khác. Một cách tuyệt vời để làm điều đó là biến mã của bạn thành một ứng dụng có thể chạy trên điện thoại Android của bạn. Để thực hiện điều này, trước tiên bạn sẽ cần phải cài đặt một gói phần mềm được gọi là 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
32 với 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
33:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

$ pip install buildozer

Sau đó, tạo một thư mục mới và điều hướng đến nó trong thiết bị đầu cuối của bạn. Khi bạn ở đó, bạn sẽ cần chạy lệnh sau:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
0

Thao tác này sẽ tạo một tệp 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
36 mà bạn sẽ sử dụng để định cấu hình bản dựng của mình. Đối với ví dụ này, bạn có thể chỉnh sửa một vài dòng đầu tiên của tệp đặc tả như sau:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
1

Bạn có thể xem qua phần còn lại của tệp để xem bạn có thể thay đổi những gì khác.

Tại thời điểm này, bạn gần như đã sẵn sàng để xây dựng ứng dụng của mình, nhưng trước tiên, bạn sẽ muốn cài đặt các phụ thuộc cho 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
32. Sau khi chúng được cài đặt, hãy sao chép ứng dụng máy tính của bạn vào thư mục mới và đổi tên nó thành 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
39. Điều này được yêu cầu bởi 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
32. Nếu bạn không có tên tệp chính xác, thì quá trình xây dựng sẽ không thành công.

Bây giờ bạn có thể chạy lệnh sau:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
2

Bước xây dựng mất nhiều thời gian, mất từ ​​15 đến 20 phút. Tùy thuộc vào phần cứng của bạn, có thể mất nhiều thời gian hơn, vì vậy hãy thoải mái lấy một tách cà phê hoặc chạy bộ trong khi chờ đợi. 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
42 sẽ tải xuống bất kỳ phần Android SDK nào nó cần trong quá trình xây dựng. Nếu mọi thứ diễn ra theo đúng kế hoạch, thì bạn sẽ có một tệp có tên dạng như 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
43 trong thư mục 
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
3 của mình.

Bước tiếp theo là kết nối điện thoại Android của bạn với máy tính và sao chép tệp 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
45 vào đó. Sau đó, bạn có thể mở trình duyệt tệp trên điện thoại của mình và nhấp vào tệp 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
45. Android sẽ hỏi bạn xem bạn có muốn cài đặt ứng dụng hay không. Bạn có thể thấy cảnh báo vì ứng dụng được tải xuống từ bên ngoài Google Play, nhưng bạn vẫn có thể cài đặt.

Đây là kết quả hiển thị trên Samsung S9:

Công cụ 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
32 này có một số lệnh khác mà bạn có thể sử dụng. Kiểm tra tài liệu để xem bạn có thể làm gì khác.

Bạn cũng có thể đóng gói ứng dụng bằng cách sử dụng 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
48 nếu bạn cần kiểm soát chi tiết hơn. Hãy xem phần bắt đầu nhanh của dự án.

Đóng gói ứng dụng của bạn cho iOS

Hướng dẫn xây dựng ứng dụng cho iOS phức tạp hơn một chút so với Android. Để có thông tin cập nhật nhất, bạn nên luôn sử dụng tài liệu đóng gói chính thức của Kivy. Bạn sẽ cần chạy các lệnh sau trước khi có thể đóng gói ứng dụng cho iOS trên máy Mac của mình:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
3

Khi tất cả chúng được cài đặt thành công, bạn sẽ cần phải biên dịch bản phân phối bằng các lệnh sau:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
4

Nếu bạn gặp lỗi cho biết 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
51 không thể tìm thấy, hãy xem câu trả lời StackOverflow này để biết các cách giải quyết vấn đề đó. Sau đó, hãy thử chạy lại các lệnh trên.

Nếu bạn gặp lỗi SSL, thì có thể bạn chưa thiết lập OpenSSL của Python. Lệnh này sẽ khắc phục điều đó:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
5

Bây giờ hãy quay lại và thử chạy lại lệnh 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
53.

Khi bạn đã chạy tất cả các lệnh trước thành công, bạn có thể tạo dự án Xcode của mình bằng cách sử dụng tập lệnh 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
53. Điểm nhập của ứng dụng chính của bạn phải được đặt tên 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
39 trước khi bạn tạo dự án Xcode. Đây là lệnh bạn sẽ chạy:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
6

Nên có một thư mục có tên 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
57 với dự án Xcode của bạn trong đó. Bây giờ bạn có thể mở dự án đó bằng Xcode và làm việc trên đó. Lưu ý rằng nếu bạn muốn gửi ứng dụng của mình lên App Store, thì bạn sẽ phải tạo tài khoản nhà phát triển và trả phí hàng năm cho họ.

Đóng gói ứng dụng của bạn cho Windows

Bạn có thể đóng gói ứng dụng Kivy của mình cho Windows bằng PyInstaller. Nếu bạn chưa từng sử dụng nó trước đây, hãy xem Sử dụng PyInstaller để Dễ dàng phân phối các ứng dụng Python.

Bạn có thể cài đặt PyInstaller bằng 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
33:
import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
7

Lệnh sau sẽ đóng gói ứng dụng của bạn:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
8

Lệnh này sẽ tạo tệp thực thi Windows và một số tệp khác. Đối số 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
61 cho PyInstaller biết rằng đây là một ứng dụng cửa sổ, chứ không phải là một ứng dụng dòng lệnh. Nếu bạn muốn PyInstaller tạo một tệp thực thi duy nhất, thì bạn có thể thêm đối số 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
62 vào 
from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
61.

Đóng gói ứng dụng của bạn cho macOS

Bạn có thể sử dụng PyInstaller để tạo tệp thực thi Mac giống như bạn đã làm cho Windows. Yêu cầu duy nhất là bạn chạy lệnh này trên máy Mac:

import kivy
import random

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

red = [1, 0, 0, 1]
green = [0, 1, 0, 1]
blue = [0, 0, 1, 1]
purple = [1, 0, 1, 1]

class HBoxLayoutExample(App):
  def build(self):
    layout = BoxLayout(padding=10)
    colors = [red, green, blue, purple]

    for i in range(5):
      btn = Button(text="Button #%s" % (i + 1),
                   background_color=random.choice(colors)
                   )

      layout.add_widget(btn)
    return layout

if __name__ == "__main__":
  app = HBoxLayoutExample()
  app.run()
4

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
9

Thao tác này sẽ tạo một tệp thực thi duy nhất trong thư mục 

from kivy.app import App
from kivy.uix.image import Image

class MainApp(App):
  def build(self):
    img = Image(source='icon_v1study.png',
                size_hint=(1, .5),
                pos_hint={'center_x': .5, 'center_y': .5})

    return img

if __name__ == '__main__':
  app = MainApp()
  app.run()
65. Tệp thực thi sẽ có cùng tên với tệp Python mà bạn đã chuyển cho PyInstaller. Nếu bạn muốn giảm kích thước tệp của tệp thực thi hoặc bạn đang sử dụng GStreamer trong ứng dụng của mình, hãy xem trang đóng gói của Kivy dành cho macOS để biết thêm thông tin.

Phần kết luận

Kivy là một framework GUI thực sự thú vị mà bạn có thể sử dụng để tạo giao diện người dùng máy tính để bàn và ứng dụng di động trên cả iOS và Android. Các ứng dụng Kivy sẽ không giống các ứng dụng gốc trên bất kỳ nền tảng nào. Đây có thể là một lợi thế nếu bạn muốn ứng dụng của mình trông khác biệt so với đối thủ!

Trong hướng dẫn này, bạn đã học những kiến ​​thức cơ bản về Kivy bao gồm cách thêm tiện ích con, kết nối sự kiện, bố trí nhiều tiện ích con và sử dụng ngôn ngữ KV. Sau đó, bạn đã tạo ứng dụng Kivy đầu tiên của mình và học cách phân phối nó trên các nền tảng khác, bao gồm cả thiết bị di động!

Có rất nhiều tiện ích và khái niệm về Kivy mà bạn chưa trình bày ở đây, vì vậy hãy nhớ xem trang web của Kivy để biết hướng dẫn, ứng dụng mẫu và hơn thế nữa.

Đọc thêm

Để tìm hiểu thêm về Kivy, hãy xem các tài nguyên sau:

  • Hướng dẫn lập trình Kivy
  • Tài liệu đóng gói của Kivy
  • Xây dựng ứng dụng GUI cho máy tính để bàn bằng Python

Để xem cách bạn có thể tạo ứng dụng dành cho máy tính để bàn với framework GUI Python khác, hãy xem Cách tạo ứng dụng GUI Python với wxPython.


Các khóa học qua video:
Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript
Hướng dẫn build app with python - xây dựng ứng dụng với python
« Prev: Python: Các hàm toán học trong Python Prev: Python: Các hàm toán học trong Python
» Next: Python: Python eval(): Đánh giá biểu thức động Next: Python: Python eval(): Đánh giá biểu thức động