Storing App Data with SQLite in a Kivy Application
In this tutorial, you will learn how to build a data-driven application using Python and Kivy, with data stored locally using SQLite. This is a practical step toward creating apps that retain user data across sessions; perfect for to-do lists, notes, expense trackers, or any form-based mobile or desktop application.
We will walk through a basic example of integrating SQLite into a Kivy app. The database will store and retrieve user-generated data dynamically within the app.
Step 1: Installing Required Libraries
Kivy comes with everything you need for the GUI. Python also includes SQLite support by default through the sqlite3 module, so no additional installation is required.
Step 2: Setting Up the Database
Before creating the user interface, we will define a simple SQLite database to store task data. Each task will have an ID and a text description.
import sqlite3
def initialize_database():
conn = sqlite3.connect("tasks.db")
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL
)
''')
conn.commit()
conn.close()
This function creates a database file named tasks.db with a single table called tasks.
Step 3: Creating the Application Layout
Now we will build the Kivy interface using BoxLayout, TextInput, Button, and Label widgets. The app will include:
- A text input to type tasks
- A button to add a task to the database
- A scrollable area to show saved tasks
- A delete button next to each task
All code will be in a single Python file.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
import sqlite3
class TaskApp(App):
def build(self):
initialize_database()
self.root_layout = BoxLayout(orientation='vertical', padding=20, spacing=10)
input_layout = BoxLayout(size_hint_y=None, height=40, spacing=10)
self.task_input = TextInput(hint_text='Enter a task')
add_button = Button(text='Add')
add_button.bind(on_press=self.add_task)
input_layout.add_widget(self.task_input)
input_layout.add_widget(add_button)
self.task_container = GridLayout(cols=1, spacing=10, size_hint_y=None)
self.task_container.bind(minimum_height=self.task_container.setter('height'))
scroll = ScrollView()
scroll.add_widget(self.task_container)
self.root_layout.add_widget(input_layout)
self.root_layout.add_widget(scroll)
self.load_tasks()
return self.root_layout
def add_task(self, instance):
task_text = self.task_input.text.strip()
if task_text:
conn = sqlite3.connect("tasks.db")
cursor = conn.cursor()
cursor.execute("INSERT INTO tasks (content) VALUES (?)", (task_text,))
conn.commit()
conn.close()
self.task_input.text = ''
self.load_tasks()
def delete_task(self, task_id):
conn = sqlite3.connect("tasks.db")
cursor = conn.cursor()
cursor.execute("DELETE FROM tasks WHERE id = ?", (task_id,))
conn.commit()
conn.close()
self.load_tasks()
def load_tasks(self):
self.task_container.clear_widgets()
conn = sqlite3.connect("tasks.db")
cursor = conn.cursor()
cursor.execute("SELECT id, content FROM tasks")
tasks = cursor.fetchall()
conn.close()
for task_id, content in tasks:
task_box = BoxLayout(size_hint_y=None, height=40, spacing=10)
label = Label(text=content, halign='left', valign='middle')
label.bind(size=label.setter('text_size'))
delete_button = Button(text='Delete', size_hint_x=None, width=80)
delete_button.bind(on_press=lambda instance, id=task_id: self.delete_task(id))
task_box.add_widget(label)
task_box.add_widget(delete_button)
self.task_container.add_widget(task_box)
Step 4: Running the Application
Save the code above in a file named task_app.py and run it with:
python task_app.py
The application window will allow users to enter tasks, view stored tasks, and delete them. All task data is stored in tasks.db and will persist across sessions.
Conclusion
You now have a fully functional Kivy application that stores user data using SQLite. This is a foundational pattern for building data-driven apps where offline persistence is required. The same codebase can be packaged for mobile platforms using tools like Buildozer for Android or PyInstaller for desktop.
This project demonstrates how to connect a local database to a modern Python interface using Kivy. From here, you can expand the app by adding search functionality, editing tasks, or syncing with an online database.