{"id":15015661,"url":"https://github.com/alexmhack/learning-kivy","last_synced_at":"2026-01-19T22:00:38.731Z","repository":{"id":48052070,"uuid":"200460970","full_name":"Alexmhack/Learning-Kivy","owner":"Alexmhack","description":"Learning to develop cross platform applications using the python Kivy library.","archived":false,"fork":false,"pushed_at":"2022-12-08T06:00:10.000Z","size":51,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-09T02:44:19.217Z","etag":null,"topics":["chat-application","desktop-application","example-project","kivy","kivy-application","kivy-framework","kivy-language","learning","learning-by-doing","python3","sockets","tutorial","tutorial-code"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alexmhack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-04T07:05:10.000Z","updated_at":"2023-08-27T01:35:45.000Z","dependencies_parsed_at":"2023-01-24T16:18:54.217Z","dependency_job_id":null,"html_url":"https://github.com/Alexmhack/Learning-Kivy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Alexmhack/Learning-Kivy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2FLearning-Kivy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2FLearning-Kivy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2FLearning-Kivy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2FLearning-Kivy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alexmhack","download_url":"https://codeload.github.com/Alexmhack/Learning-Kivy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexmhack%2FLearning-Kivy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28587019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T20:45:59.482Z","status":"ssl_error","status_checked_at":"2026-01-19T20:45:41.500Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat-application","desktop-application","example-project","kivy","kivy-application","kivy-framework","kivy-language","learning","learning-by-doing","python3","sockets","tutorial","tutorial-code"],"created_at":"2024-09-24T19:47:45.314Z","updated_at":"2026-01-19T22:00:38.711Z","avatar_url":"https://github.com/Alexmhack.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Learning-Kivy\nLearning to develop cross platform applications using the python Kivy library.\n\n**There has been some issues with the kivy when doing a relative import in any of the file and running the file, the kivy window does not seem to work, the application works fine in the command prompt, if anybody knows whats wrong or wanna know more about the problem, open a issue on the repo and answer it please.**\n\n## Installation\nFollow the instructions on the kivy official [website](https://kivy.org/#download) for your\noperating system and install the latest version of kivy.\n\nOptionally you can install the kivy examples which are by the way very useful for learning\nthe code base of other kivy applications, install the examples using,\n\n```\npython -m pip install kivy_examples==1.11.1\n```\n\n**1.11.1** is the latest version of kivy as of today, yours might be different or same, anyway\ninstall it, if you get any errors google it and there are is a huge community of kivy developers\nwho have answered many questions related to many problems.\n\nHopefully you have installed all of this inside a virtualenv as in the instructions given\nduring installation, so now inside you virtualenv start by writing your first kivy app.\n\n## First App\nCode is [here](https://github.com/Alexmhack/Learning-Kivy/blob/master/kivyapp/app_v0.py)\n\nCreate a new python file naming it whatever you want and inside it write your basic kivy *App*\n\n```\nimport kivy\n\nfrom kivy.app import App\nfrom kivy.uix.label import Label\n\nkivy.require('1.11.1') # replace with your current kivy version !\n```\n\nWe will be subclassing the kivy **App** and implementing its **build()** method to return\na widget instance.\n\n```\n...\nclass TestApp(App):\n    def build(self):\n        return Label(text=\"Hey there\")\n\n\nif __name__ == '__main__':\n    TestApp().run()\n```\n\nHere we create a object of our *App* class and call its *run* method, you can also do the same\nusing,\n\n```\nif __name__ == '__main__':\n    test_app = TestApp()\n    test_app.run()\n```\n\nNow run `python your-file-name.py` and if your kivy installation is fine then a window will\nappear with the *Label* `Hey there` in the center of the window.\n\n## Grid Layout\nCode can be in **testing/grid_layout_example.py**\\\nSo just like we align rows and columns in HTML and CSS, kivy is somewhat similar but with\nlittle less customizable. You can use the `kivy.uix.gridlayout` to divide the layout into\ncolumns and place widgets in the layouts or create layouts inside a layout itself.\n\nUsing grid layout is very simple, you can just import it and divide the layout first by,\n\n```\nfrom kivy.uix.gridlayout import GridLayout\n\nclass ConnectPage(GridLayout):\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self.cols = 2 # diving the layout into two cols\n```\n\nNow we need to add widgets into our columns, the order of adding widgets will be the same\norder in which the widgets are displayed in the layout.\n\nFor example, we add widgets into the layout using,\n\n```\nclass ConnectPage(GridLayout):\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self.cols = 2 # diving the layout into two cols\n\n        self.add_widget(Label(text=\"First column in the layout.\"))\n        self.add_widget(Label(text=\"Second column.\"))\n```\n\nNow that we have divided the layout into two columns, adding two widgets like we did above will\nplace the labels side by side on the same screen.\n\n## Text Input\ncode piece is in **testing/text_input_example.py**\nFor taking input from the users kivy has input fields like the `TextInput`, we can place this\nfield in one of the column and a label in the second column for e.g.\n\n```\nfrom kivy.uix.textinput import TextInput\n...\n\nclass ConnectPage(GridLayout):\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self.cols = 2 # diving the layout into two cols\n\n        self.add_widget(Label(text=\"First column in the layout.\"))\n        self.add_widget(TextInput(multiline=False))\n...\n```\n\nImport `TextInput` from `kivy.uix.textinput` and use it simple by creating a instance of it\nlike the code piece above, `multiline=False` will make sure that the input from the user does\nnot go in the second line (multiline).\n\nRun the file just like you would run any python program and you will find the text input in\nthe second column of the layout in which you can enter your input.\n\nNow try adding more *Label* and *TextInput* in the same way and you will find that the labels\nand inputs will be placed in their respective columns and row.\n\n## Button \u0026 Events\ncode is in **testing/button_event_eg.py**\n\nLets move on and build a chat application using kivy and python sockets. (I have followed the\ntutorial from [sentdex](https://www.youtube.com/playlist?list=PLQVvvaa0QuDfwnDTZWw8H3hN_VRQfq8rF))\n\nSo to know when user wants to connect to the chat socket we need to provide the user a button\nand catch the event from the button to finally connect.\n\nKivy has *Button* for this,\n\n```\nfrom kivy.uix.button import Button\n\n# moving on with out connect page\nclass ConnectPage(GridLayout):\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self.cols = 2 # diving the layout into two cols\n\n        # add or change this if you haven't\n        self.add_widget(Label(text=\"IP Address:\"))\n        self.add_widget(TextInput(multiline=False))\n\n        self.add_widget(Label(text=\"Port:\"))\n        self.add_widget(TextInput(multiline=False))\n\n        self.add_widget(Label(text=\"Username:\"))\n        self.add_widget(TextInput(multiline=False))\n\n        self.join = Button(text=\"Join\")\n        self.add_widget(self.join)\n```\n\nThe button will be placed in the first column leaving the second column empty, so we can\nadd a empty *Label* in the second column making it look a little good.\n\n```\n        ...\n        self.join = Button(text=\"Join\")\n        self.add_widget(Label())\n        self.add_widget(self.join)\n```\n\nNow what is left is making the button work or binding an method to the button click / press\nevent. We will be doing this by using the `.bind` method of `Button` instance.\n\n```\n        ...\n        self.join = Button(text=\"Join\")\n        self.join.bind(on_press=self.join_button)\n        self.add_widget(Label())\n        self.add_widget(self.join)\n\n    def join_button(self, instance):\n        port = self.port.text\n        ip = self.ip.text\n        username = self.username.text\n        print(f\"Attempting to join {ip}:{port} as {username}\")\n```\n\n**Note:** Following the tutorial, I have also implemeted the initial filling of input fields\nby writing them to a file first and then reading from the file on next run of App.\n\nYou can find this implementation in the same file.\n\n## Screen Manager \u0026 Screen\nFor code look at **testing/screen_example.py**\n\nSo why do we need **Screens**. Take example of our chat application, we want the user to input\ntheir details like the username, ip, port when the application starts and then when users\npresses the button(join) we take the user to the screen where we tell him that we are\nconnecting the user to the specific socket with whatever username that he wants.\n\nSo for navigating across the pages of connect, info and chat page we need various screens\nwith the relevant data to be shown to the user, we achieve this using **Screens**.\n\nTo create a screen and manager for screen use,\n\n```\nfrom kivy.uix.screenmanager import ScreenManager, Screen\n...\n...\nclass TestApp(App):\n    def build(self):\n        self.screen_manager = ScreenManager()\n\n        self.connect_page = ConnectPage()\n        screen = Screen(name=\"Connect\")\n        screen.add_widget(self.connect_page)\n        self.screen_manager.add_widget(screen)\n\n        self.info_page = InfoPage()\n        screen = Screen(name=\"Info\")\n        screen.add_widget(self.info_page)\n        self.screen_manager.add_widget(screen)\n        return self.screen_manager\n```\n\n`self.connect_page` is the instance of `ConnectPage` class. We also create a object of `Screen`\nclass with the `name=\"Connect\"`, the name attribute helps us to refer to this screen using the\n**ScreenManager** object. Similarly we create a instance of **InfoPage** class which is not\nyet defined but you can look in the file for reference. After we add the **GridLayout**\ninstances to the screen using `screen.add_widget(self.connect_page)`, since we need to return\nsomething from the `build` method we return the `screen_manager` itself.\n\nNow we can change the screens using,\n\n```\n    # inside ConnectPage class\n    ....\n    def join_button(self, instance):\n        ip = self.ip.text\n        port = self.port.text\n        username = self.username.text\n\n        with open('data/prev_details.txt', 'w') as file:\n            file.write(f\"{ip},{port},{username}\")\n\n        info = f\"Attempting to join {ip}:{port} as {username}\"\n        chat_app.info_page.update_info(info)\n        chat_app.screen_manager.current = \"Info\"\n```\n\nMake changes accordingly using **testing/screen_example.py** file and run it, after entering\nthe input press join button and you will get the info page showing your details.\n\nHere is how `InfoPage` class looks like,\n\n```\nclass InfoPage(GridLayout):\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self.cols = 1\n\n        self.message = Label(halign='center', valign='middle', font_size=30)\n        self.message.bind(width=self.update_message_width)\n        self.add_widget(self.message)\n\n    def update_info(self, message):\n        self.message.text = message\n\n    def update_message_width(self, *_):\n        self.message.text_size = (self.message.width * 0.9, None)\n```\n\nWe bind the `width` of the message to a method which will update the `text_size` of the message\nto the 90% of the message width. We also define a method `update_info` which will update the\n*message* of the page to the message passed to it as argument.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexmhack%2Flearning-kivy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexmhack%2Flearning-kivy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexmhack%2Flearning-kivy/lists"}