Sant 的kivy視頻筆記 1 - 图1
© karobben

由於語法渲染問題而影響閱讀體驗, 請移步博客閱讀~
本文GitPage地址

Introduction of kivy:
Youtube Vedio
Text Tutorial

Installation: Skip

python: python=3.7.5 is strongly recommended!!
If you wants to know why, go to check This blog

So, if you want to write an app for windows, linux, IOS, and Android with only one set of code, then, Kivy is the best choice for you.

Hello World

first, you’d like to import kivy and from kivy.app import App;
Then, you’d like from kivy.uix.label import Label so you can add some text
Add kivy.require("1.10.1") to assign the version of the kivy. (PS: actually, mine is 1.11.1)

Then, we can start to class a class EpicApp(App)

  1. import kivy
  2. from kivy.app import App
  3. from kivy.uix.label import Label # so you can add some text
  4. kviy.require("1.10.1") # Assign the version of the kivy so every body would be on the same page
  5. class EpicApp(App):
  6. ''' After class, we'd like to initializing the App'''
  7. def build(self):
  8. return Label(text="Hello world")
  9. if __name__ == "__main__":
  10. EpicApp().run()

So, it’ll be your first kivy app!
Sant 的kivy視頻筆記 1 - 图2

It is not interesting at all, actually. So, Let’s move one for GridLayout

GridLayout

Now, let’s add from kivy.uix.gridlayout import GridLayout to import the Layout style for organizing sort of things;
from kivy.uix.textinput import TextInput to add a TextInput box.

Now, Our class are becoming more complicated
So, during the initiation in build section, we not return to a simple text Label anymore. Let’s say, to return to a class named ConnectPage.

And let’s sorting stuff in ConnectPage by GridLayout

  1. import kivy
  2. from kivy.app import App
  3. from kivy.uix.label import Label
  4. from kivy.uix.gridlayout import GridLayout # one of many layout structures
  5. from kivy.uix.textinput import TextInput # allow for ...text input.
  6. kivy.require("1.10.1")
  7. ## An actual app is likely to consist of many different
  8. ## "pages" or "screens." Inherit from GridLayout
  9. class ConnectPage(GridLayout):
  10. # runs on initialization
  11. def __init__(self, **kwargs):
  12. # we want to run __init__ of both ConnectPage AAAAND GridLayout
  13. super().__init__(**kwargs)
  14. self.cols = 2 # used for our grid
  15. # widgets added in order, so mind the order.
  16. self.add_widget(Label(text='IP:')) # widget #1, top left
  17. self.ip = TextInput(multiline=False) # defining self.ip...
  18. self.add_widget(self.ip) # widget #2, top right
  19. self.add_widget(Label(text='Port:'))
  20. self.port = TextInput(multiline=False)
  21. self.add_widget(self.port)
  22. self.add_widget(Label(text='Username:'))
  23. self.username = TextInput(multiline=False)
  24. self.add_widget(self.username)
  25. class EpicApp(App):
  26. def build(self):
  27. return ConnectPage()
  28. if __name__ == "__main__":
  29. EpicApp().run()

Sant 的kivy視頻筆記 1 - 图3

And that is what will we get! Awesome, hum?

Lesson3

  1. import socket
  2. import errno
  3. from threading import Thread
  4. HEADER_LENGTH = 10
  5. client_socket = None
  6. ## Connects to the server
  7. def connect(ip, port, my_username, error_callback):
  8. global client_socket
  9. # Create a socket
  10. # socket.AF_INET - address family, IPv4, some otehr possible are AF_INET6, AF_BLUETOOTH, AF_UNIX
  11. # socket.SOCK_STREAM - TCP, conection-based, socket.SOCK_DGRAM - UDP, connectionless, datagrams, socket.SOCK_RAW - raw IP packets
  12. client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  13. try:
  14. # Connect to a given ip and port
  15. client_socket.connect((ip, port))
  16. except Exception as e:
  17. # Connection error
  18. error_callback('Connection error: {}'.format(str(e)))
  19. return False
  20. # Prepare username and header and send them
  21. # We need to encode username to bytes, then count number of bytes and prepare header of fixed size, that we encode to bytes as well
  22. username = my_username.encode('utf-8')
  23. username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')
  24. client_socket.send(username_header + username)
  25. return True
  26. ## Sends a message to the server
  27. def send(message):
  28. # Encode message to bytes, prepare header and convert to bytes, like for username above, then send
  29. message = message.encode('utf-8')
  30. message_header = f"{len(message):<{HEADER_LENGTH}}".encode('utf-8')
  31. client_socket.send(message_header + message)
  32. ## Starts listening function in a thread
  33. ## incoming_message_callback - callback to be called when new message arrives
  34. ## error_callback - callback to be called on error
  35. def start_listening(incoming_message_callback, error_callback):
  36. Thread(target=listen, args=(incoming_message_callback, error_callback), daemon=True).start()
  37. ## Listens for incomming messages
  38. def listen(incoming_message_callback, error_callback):
  39. while True:
  40. try:
  41. # Now we want to loop over received messages (there might be more than one) and print them
  42. while True:
  43. # Receive our "header" containing username length, it's size is defined and constant
  44. username_header = client_socket.recv(HEADER_LENGTH)
  45. # If we received no data, server gracefully closed a connection, for example using socket.close() or socket.shutdown(socket.SHUT_RDWR)
  46. if not len(username_header):
  47. error_callback('Connection closed by the server')
  48. # Convert header to int value
  49. username_length = int(username_header.decode('utf-8').strip())
  50. # Receive and decode username
  51. username = client_socket.recv(username_length).decode('utf-8')
  52. # Now do the same for message (as we received username, we received whole message, there's no need to check if it has any length)
  53. message_header = client_socket.recv(HEADER_LENGTH)
  54. message_length = int(message_header.decode('utf-8').strip())
  55. message = client_socket.recv(message_length).decode('utf-8')
  56. # Print message
  57. incoming_message_callback(username, message)
  58. except Exception as e:
  59. # Any other exception - something happened, exit
  60. error_callback('Reading error: {}'.format(str(e)))

Enjoy~

本文由Python腳本GitHub/語雀自動更新

由於語法渲染問題而影響閱讀體驗, 請移步博客閱讀~
本文GitPage地址

GitHub: Karobben
Blog:Karobben
BiliBili:史上最不正經的生物狗