![]() |
|---|
| © 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)
import kivyfrom kivy.app import Appfrom kivy.uix.label import Label # so you can add some textkviy.require("1.10.1") # Assign the version of the kivy so every body would be on the same pageclass EpicApp(App):''' After class, we'd like to initializing the App'''def build(self):return Label(text="Hello world")if __name__ == "__main__":EpicApp().run()
So, it’ll be your first kivy app!

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
import kivyfrom kivy.app import Appfrom kivy.uix.label import Labelfrom kivy.uix.gridlayout import GridLayout # one of many layout structuresfrom kivy.uix.textinput import TextInput # allow for ...text input.kivy.require("1.10.1")## An actual app is likely to consist of many different## "pages" or "screens." Inherit from GridLayoutclass ConnectPage(GridLayout):# runs on initializationdef __init__(self, **kwargs):# we want to run __init__ of both ConnectPage AAAAND GridLayoutsuper().__init__(**kwargs)self.cols = 2 # used for our grid# widgets added in order, so mind the order.self.add_widget(Label(text='IP:')) # widget #1, top leftself.ip = TextInput(multiline=False) # defining self.ip...self.add_widget(self.ip) # widget #2, top rightself.add_widget(Label(text='Port:'))self.port = TextInput(multiline=False)self.add_widget(self.port)self.add_widget(Label(text='Username:'))self.username = TextInput(multiline=False)self.add_widget(self.username)class EpicApp(App):def build(self):return ConnectPage()if __name__ == "__main__":EpicApp().run()

And that is what will we get! Awesome, hum?
Lesson3
import socketimport errnofrom threading import ThreadHEADER_LENGTH = 10client_socket = None## Connects to the serverdef connect(ip, port, my_username, error_callback):global client_socket# Create a socket# socket.AF_INET - address family, IPv4, some otehr possible are AF_INET6, AF_BLUETOOTH, AF_UNIX# socket.SOCK_STREAM - TCP, conection-based, socket.SOCK_DGRAM - UDP, connectionless, datagrams, socket.SOCK_RAW - raw IP packetsclient_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:# Connect to a given ip and portclient_socket.connect((ip, port))except Exception as e:# Connection errorerror_callback('Connection error: {}'.format(str(e)))return False# Prepare username and header and send them# We need to encode username to bytes, then count number of bytes and prepare header of fixed size, that we encode to bytes as wellusername = my_username.encode('utf-8')username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')client_socket.send(username_header + username)return True## Sends a message to the serverdef send(message):# Encode message to bytes, prepare header and convert to bytes, like for username above, then sendmessage = message.encode('utf-8')message_header = f"{len(message):<{HEADER_LENGTH}}".encode('utf-8')client_socket.send(message_header + message)## Starts listening function in a thread## incoming_message_callback - callback to be called when new message arrives## error_callback - callback to be called on errordef start_listening(incoming_message_callback, error_callback):Thread(target=listen, args=(incoming_message_callback, error_callback), daemon=True).start()## Listens for incomming messagesdef listen(incoming_message_callback, error_callback):while True:try:# Now we want to loop over received messages (there might be more than one) and print themwhile True:# Receive our "header" containing username length, it's size is defined and constantusername_header = client_socket.recv(HEADER_LENGTH)# If we received no data, server gracefully closed a connection, for example using socket.close() or socket.shutdown(socket.SHUT_RDWR)if not len(username_header):error_callback('Connection closed by the server')# Convert header to int valueusername_length = int(username_header.decode('utf-8').strip())# Receive and decode usernameusername = client_socket.recv(username_length).decode('utf-8')# 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)message_header = client_socket.recv(HEADER_LENGTH)message_length = int(message_header.decode('utf-8').strip())message = client_socket.recv(message_length).decode('utf-8')# Print messageincoming_message_callback(username, message)except Exception as e:# Any other exception - something happened, exiterror_callback('Reading error: {}'.format(str(e)))
Enjoy~
由於語法渲染問題而影響閱讀體驗, 請移步博客閱讀~
本文GitPage地址
GitHub: Karobben
Blog:Karobben
BiliBili:史上最不正經的生物狗

