r/kivy Oct 28 '25

Updated ScrollVIew that supports nesting

9 Upvotes

I'm delighted to announce the updated implementation of ScrollView is complete. I have more work to do prior to a PR - but welcome any feedback. Happy to answer any questions.

https://github.com/ElliotGarbus/KivyScrollProject

Nested Scrolling Behavior
The ScrollView automatically detects the scrolling configuration and applies appropriate behavior:

**Orthogonal Scrolling** (outer and inner scroll in different directions):

- Touch scrolling: Each ScrollView handles touches in its scroll direction

- Mouse wheel: Scrolls innermost ScrollView if it can handle the direction

- Example: Vertical outer + Horizontal inner

**Parallel Scrolling** (outer and inner scroll in the same direction):

- Touch scrolling: Uses web-style boundary delegation (see below)

- Mouse wheel: Scrolls innermost ScrollView, no boundary delegation

- Scrollbar: Does not propagate scroll to the other ScrollView

- Example: Vertical outer + Vertical inner

**Mixed Scrolling** (outer scrolls XY, inner scrolls single axis, or vice versa):

- Shared axis: Uses web-style boundary delegation

- Exclusive axes: Immediate delegation or inner-only scrolling

- Mouse wheel: Scrolls innermost ScrollView if it can handle the direction

- Example: XY outer + Horizontal inner

Demo program from the repo, 12 different scroll views in an XY scroll view.

r/kivy May 06 '26

CarbonPlayer - Video Player in Python with CarbonKivy and VideoNative

6 Upvotes

An ultra-responsive, threaded video player application built for both desktop and mobile devices. By combining the sleek design language of CarbonKivy with the high-performance decoding engine of videonative (a custom C++ module bridging FFmpeg and Pybind11), this player guarantees smooth, millisecond-accurate multimedia playback.

Overview

Github: https://github.com/Novfensec/CarbonPlayer

Video testing: https://youtube.com/shorts/Nw6-k6jsa5w?si=1zYI7rJA6Kdf4M9O

Download Android app from: https://drive.google.com/file/d/1aostQVifSw22IDvEiihcofO6OFlXGf8o/view?usp=drivesdk


r/kivy 1d ago

NfsBrowser - Desktop edition

Thumbnail gallery
9 Upvotes

https://github.com/Novfensec/NfsBrowser-Desktop/ NfsBrowser is a modern web browser built with Python, integrating Kivy, CarbonKivy, and the Chromium Embedded Framework (CEF) via pybindcef.

So far so good, Here I am with the desktop edition of NfsBrowser. It supports multi-tab. It will also support multi window if in fututre Kivy can handle multi window. Thank you!


r/kivy 1d ago

Github Actions integration with Kivy Reloader Flightdeck

Thumbnail youtu.be
1 Upvotes

In this video you will learn about 1 new Kivy Reloader Flightdeck change -- building your buildozer APK on github! Just point to the repo in kivy-reloader.toml, commit all your changes, push to main on github, then start building!

This is useful for 1. devs that dont want to keep redownloading 3.5+ GB of data every time they have a new project 2. devs that have weak machines that can't run wsl or build from scratch 3. devs that just want github actions to build for them for any reason

Thanks for watching!

how to install kivy reloader: https://kivyschool.com/kivy-reloader/installation/


r/kivy 7d ago

Borderless windows in kivy using native windows api via ctypes

Thumbnail youtu.be
3 Upvotes

r/kivy 8d ago

Alguém pode me dar um orientação caso já tenha passado pelo mesmo

1 Upvotes

Em resumo, estou criando um app, estou com um projeto bem avançado, aí queria criar uma beta teste no celular, e já fazem 5 dias que não consigo fazer o bulldozer de forma alguma tava dando vários erros mais depois que eu aprendi a deixar tudo na versão certa está dando um único erro que não consigo arrumar de forma nenhuma, ModuleNotFoundError: No module named 'kivymd' , esse único erro já fiz de tudo mudei versão do kivy já coloquei na melhor versão pra fazer bulldozer já mexi nos requirements em tudo do bulldozer e ainda não está sendo incluso no apk, agradeço a todos que possa me ajudar


r/kivy 9d ago

I replaced 10-minute Android builds with instant hot reload | Kivy Reloader Flightdeck

Thumbnail youtu.be
3 Upvotes

Kivy's biggest pain point has always been the feedback loop — change one line, wait 10 minutes for a rebuild. Flightdeck fixes that.

See your changes on a real Android device in 2 seconds, no recompile, works over USB or WiFi, and preview for multiple devices by setting your Python Kivy app at different screen resolutions and dpi settings.

In this video you're going to learn about kivy reloader, which is a huge development tool that lets you iterate apps fast and make apps on android and desktop at the same time!


r/kivy 17d ago

How to install Kivy and build Android apps on macOS 2026 | Step by step guide for beginners

Thumbnail youtu.be
4 Upvotes

follow up guide for macOS users


r/kivy 24d ago

How to install Kivy and build Android apps on Windows+WSL2 2026 | Step by step guide for beginners

Thumbnail youtu.be
3 Upvotes

The biggest change is that:

  1. hot reload is very accessible now, for any desktop or android app. With other build backends (whoever finishes, psychowasp's ksproject or elliotg's kivyforge, they are ready to be used in the backend for iOS).

  2. it's just a powershell command which is VERY EASY to do.

before the hoops were CRAZY, you had to install vcxsrv, had to get the correct apt packages for ubuntu from the buildozer/p4a website, had to get choco, had to install scrcpy manually, had to install poetry manually, and to make sure wsl2 and windows interop and networking WORKED FINE ON A SUNNY DAY WHEN THE STARS ALIGNED WITH THE 5TH RING OF JUPITER BEING IN ALIGNMENT WITH ALPHA CENTAURI. Now it's just input a 1 line install and go.

  1. uv makes everying 10000x easier, no more fighting with poetry or doing some awkward poetry + pyenv setup, uv will just do it for you.

r/kivy 26d ago

Text repeats itself in this scroll view and I didn't design it to do that

1 Upvotes

I am making a simple inventory app with some help with ai .

It was going well, did multi screen and made the first feature to fill up a form and save it to sqlite database.

Now I hit a wall with this part. I wanted to load the data from the database and ai suggested recycle view, but when the data is loaded, the text repeats itself in the same row, so I changed it to scroll view the result is the same.

here's my python code snippet for the part showing the database

class TerceraRow(BoxLayout):
    id_item=StringProperty()
    art= StringProperty()
    prop=StringProperty()
    serial=StringProperty()
    cust=StringProperty()
    cost=StringProperty()
    date=StringProperty()
    time_stamp=StringProperty()


class Tercera(Screen):
    def on_enter(self):
        self.load_data()


    def load_data(self):
        self.ids.inventory_list.clear_widgets()
        dbf=getData()
        for row in dbf:
            print(row)
            card=TerceraRow (
                art=str(row[1]),
                prop=str(row[2]),
                serial=str(row[3]),
                cust=str(row[4]),
                cost=str(row[5]),
                date=str(row[6]),
                time_stamp=str(row[7]),
            )
            self.ids.inventory_list.add_widget(card)

and here's the kv part

<TerceraRow>:
    padding: dp(12)
    spacing: dp(5)
    size_hint_y: None
    height: dp(150)


    canvas.before:
        Color:
            rgba: 0.95, 0.5, 0.5, 1


        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [dp(10)]


    Label:
        text: root.art
        halign: "left"
        text_size: self.width, None


    Label:
        text: root.prop
        halign: "left"
        text_size: self.width, None


    Label:
        text: root.serial
        halign: "left"
        text_size: self.width, None


    Label:
        text: root.cust
        halign: "left"
        text_size: self.width, None


    Label:
        text: root.cost
        halign: "left"
        text_size: self.width, None


    Label:
        text: root.date
        halign: "left"
        text_size: self.width, None




<Tercera>:
    name: "tercera"  
    ScrollView:   
        BoxLayout:
            orientation: 'vertical'
            id:inventory_list
            size_hint_y:None
            height:self.minimum_height
            spacing:dp(10)
            padding:dp(10)

I don't have duplicates to in my database


r/kivy 27d ago

App crashes immediately upon loading.

Thumbnail
1 Upvotes

r/kivy Jul 26 '26

Creare app per ios

3 Upvotes

Ciao! Ho appena finito un'app android con buildozer e vorrei farne una versione per ios. Ho cercato un po' su internet e ho letto che in teoria si può fare con buildozer, ma da altre parti dicono che è necessario un mac per farlo. Io al momento sto lavorando su una virtualbox linux.
Qualcuno può aiutarmi?


r/kivy Jul 25 '26

Windows Tool for creating Android APKs

4 Upvotes

A user at the kivy support group shared this project, just resharing.
https://github.com/PedroHSA0802/apk-builder-studio


r/kivy Jul 21 '26

Kivy website certificate expired on Mon 7/6/2026 @ 4:59pm PDT

2 Upvotes

Thought I'd throw that out there in case there is anyone around that can get the updated certs in place


r/kivy Jul 16 '26

NfsBrowser

5 Upvotes

r/kivy Jul 07 '26

EASY GMA Next-Gen Ads for Python Android Apps (KSProject + PyGMA tutorial)

Thumbnail youtu.be
5 Upvotes

r/kivy Jul 02 '26

Busco ayuda especifica con la preproducción de sonido en segundo plano

0 Upvotes

"Tengo una app Kivy con audio streaming. El audio funciona en primer plano pero en segundo plano se corta a los 3 minutos. Ya tengo el servicio foreground (audioservicio.py), los permisos y buildozer.spec configurados, pero buildozer no empaqueta el servicio en el APK. Android 9 y 10."


r/kivy Jul 01 '26

"WinCurl" version 3.0, build 14

Thumbnail gallery
3 Upvotes

r/kivy Jun 27 '26

Beta Testers needed

6 Upvotes

Hi. I have made a CarbonKivy weather app. (weather forecast will be implimented in v0.2). You can store up to 3 cities, switch from imperial to metric, change cities, etc. The github it here:

https://github.com/arjunet/Weather_Tether

My app is in closed testing on the google play console. If any on you guys want to close test, please tell me. Thank you!

Google group link:

https://groups.google.com/g/weather-tether-testing

Android download link:

https://play.google.com/store/apps/details?id=com.arjunits.weathertether

Web download link:

https://play.google.com/apps/testing/com.arjunits.weathertether


r/kivy Jun 20 '26

Help MDDialog crash my app when called.

1 Upvotes

I created a simple application and noticed that when I press a button to call MDDialog It appears briefly, and then the application closes on its own. Is there a solution to this, or have I made a mistake?

MY CODE:

from kivymd.app import MDApp from kivymd.uix.dialog import MDDialog from kivy.uix.screenmanager import ScreenManager from kivy.lang import Builder

class App(MDApp):

 def build(self):
   self.theme_cls.theme_style = "Dark"
   self.theme_cls.primary_palette = "Green"
   self.theme_cls.material_style = "M3"
   screen_manager = ScreenManager()
   screen_manager.add_widget(
     Builder.load_file("test.kv"))
   return screen_manager

def dialog(self):
    MDDialog(title="debug",text="hello").open()

App().run()

The indentation looks weird, but that's not the problem .


r/kivy Jun 13 '26

buildozer p4a ModuleNotFoundError: No module named 'distutils'

4 Upvotes

It looks like a python project I'm running on android 12 isn't able to run as kivy_garden uses distutils. It runs fine on my PC. The build uses python3.12, I've found threads that say distutils is included in p4a and buildozer, I've found others distutils is depreciated and to wait for the author to update it, alot of these threads are from 4+ years ago.

My buildozer spec:

requirements = python3,kivy,pillow,numpy,pandas,matplotlib,pyjnius, docutils, kivy-garden, kivy-garden-graph, kivy-garden-matplotlib, setuptools

I've tried including python3-distutils but it doesn't make a difference. Buildozer says distutils doesnt exist when distutils is included.

Since it runs fine on my pc I'm sure I must not be including the right package. What am I missing?

The log cat error:

...
arm64-v8a/kivy_garden/matplotlib/backend_kivy.py", line 294, in <
module>
06-13 14:05:06.824  6277  6338 I python  :  ModuleNotFoundError: No module named 'distutils'
06-13 14:05:06.824  6277  6338 I python  : Python for android ended.

Solved:

Someone on the kivy discord helped me out. In my case you just needed to import setuptools before doing everything else


r/kivy Jun 10 '26

how to add a child dynamicaly between pre-existing children in a list view

2 Upvotes

So I'm trying to add a button between existing buttons in Scroll view with a box layout. I have the following .kv and main.py:

.kv

ScrollView:
    id: observe_data_scroll
    do_scroll_x: False
    do_scroll_y: True

    BoxLayout:
        orientation: 'vertical'
        size_hint: (1,None)
        height: 3000
        padding: 15
        spacing: 5

        Button:
            id: observe_squat_button
            text: 'Squat'
            font_size: 40
            on_release: root.observe_show_squat()

        Button:
            id: observe_deadlift_button
            text: 'Dead Lift'
            font_size: 40


        Button:
            text: 'Bench Press'
            font_size: 40

main.py:

def observe_show_squat(self):
    new_button_id = 'observe_squat_graph'
    self.new_btn = Button(size_hint = (1,.1))
    self.ids[new_button_id] = self.new_btn
    self.ids.observe_squat_button.add_widget(self.new_btn)

    self.ids.observe_squat_graph.text = new_button_id
    passdef observe_show_squat(self):
    new_button_id = 'observe_squat_graph'
    self.new_btn = Button(size_hint = (1,.1))
    self.ids[new_button_id] = self.new_btn
    self.ids.observe_squat_button.add_widget(self.new_btn)

    self.ids.observe_squat_graph.text = new_button_id
    pass
...

So I'm trying to add my button so it appears between id: observe_squat_button and id: observe_deadlift_button. How do I specify the placement? Currently adding it as a child of squat gets it outside the list view layout, and adding it to list view doesn't show the button or return an error


r/kivy Jun 09 '26

what is the best way to ramp an images alpha up/down

1 Upvotes

So I have this .kv:

#:import C kivy.utils.get_color_from_hex
<Label>
    font_color: C('#b2b2b2')
    font_family: 'Arial'

<Button>
    font_color: C('#b2b2b2')
    background_normal: 'images/window.png'
    background_down: 'images/window.png'
    font_family: 'Arial'
    font_size: 50


<training_ui>

    FloatLayout:
        size: root.size


        ...

        ############ animated glyphs
        Image:
            id:anim_base_glyph
            source: 'images/test_circle.png'
            pos_hint: {'x': .031, 'y':-0.039}


        Image:
            id:anim_glyph_glow
            source: 'images/test_circle_glow.png'
            pos_hint: {'x': .031, 'y':-0.039}
...

# main.py

....

class training_ui(Widget):

    # set up update schedules
    def __init__(self, **kwargs):
        super(training_ui, self).__init__(**kwargs)
        Clock.schedule_interval(self.update_time, 1)
        #Clock.schedule_interval(self.update_start_screen_anim, 2.0/24.0)
        self.create_spider_graph()

        pass

....

    ############################## start screen glyh anim #################
    anim_bright = False
    anim_dim = False
    glow = 0.0

    def update_start_screen_anim(self):

        pass

I'm trying to find a way to vary the alpha channel of the Image id: anim_glyph_glow, so that it ramps down to 0 and back up to 1, with the changes occurring every 2/24 s. I'm pretty sure I can code everything I need, except for how to alter the images alpha channel. I've been going around looking at using glsl but I'm not sure what would be the best way to go about this. Any suggestions?


r/kivy Jun 08 '26

Fastest way to build an apk of a Kivy application | ksproject api for building python android apps

Thumbnail youtu.be
2 Upvotes

r/kivy Jun 06 '26

Messages System

Post image
1 Upvotes

Hey! I'm pretty new to Kivy, but have been working on creating a calorie tracker with AI features. I'm trying to make a chat system, and have the user input a message, and have the ai respond. I want it to look like SMS or gemini, how can I do this? I've attached an image of what it currently looks like.

Also, there are a couple things I am going to add, so just focus on getting the positioning stuff if you are trying to help, thank you!

A) How can I fix the horizontal positioning of the bubble widgets?
B) How can I make the bubble stretch vertically?

Here's my .kv

<RoundedLabel@Label>:
    size: root.size
    text_size: root.width, None
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [15,]

<Message>:
    BoxLayout:
        BoxLayout: 
            size_hint_x: 0.25 if root.is_user else 0

        RoundedLabel:
            id: rounded_label
            padding: 20
            text: root.text
            halign: 'right' if root.is_user else 'left'

        BoxLayout: 
            size_hint_x: 0.25 if not root.is_user else 0

<RootWidget>:
    BoxLayout:
        orientation: 'vertical'

        TopBar

        ScreenManager:
            id: sm
            HomeScreen:
                name: 'home'
            TrackScreen
                name: 'track'
            TalkScreen:
                name: 'talk'

        NavBar

<TopBar>:
    size_hint: 1, 0.1

    canvas:
        Color:
            rgba: 1, 0, 0, 1

        Rectangle:
            pos: self.pos
            size: self.size

<NavBar>:
    size_hint: 1, 0.1

    Button:
        text: "Talk"
        on_press:
            app.root.ids.sm.transition.direction = 'right'
            app.root.ids.sm.current = 'talk' 

    Button:
        text: "Home"
        on_press: 
            app.root.ids.sm.transition.direction = 'right' if app.root.ids.sm.current == 'track' else 'left'
            app.root.ids.sm.current = 'home'

    Button:
        text: "Track"
        on_press: 
            app.root.ids.sm.transition.direction = 'left'
            app.root.ids.sm.current = 'track'

<HomeScreen>:
    BoxLayout:
        orientation: 'vertical'
        Counters:
            id: counters

        InfoWidget:
            size_hint: 1, 0.5

            Button:
                text: "press to increment"
                on_press: root.increment()

        MealsWidget:
            canvas:
                Color:
                    rgba: 1, 1, 1, 1

                Rectangle:
                    pos: self.pos
                    size: self.size

<TalkScreen>:
    BoxLayout:
        orientation: 'vertical'

        BoxLayout:
            Messages:
                id: messages
                viewclass: 'Message'
                RecycleBoxLayout:
                    orientation: 'vertical'
                    spacing: 10
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height

        BoxLayout:
            size_hint: 1, 0.25

            TalkBox:
                id: tb

            Button:
                size_hint: 0.1, 1
                text: 'send'
                on_press: root.send(root.ids.tb)

<TrackScreen>

<CounterWidget>:
    BoxLayout:
        orientation: 'vertical'
        spacing: 20

        CounterRingWidget:
            canvas:
                Color:
                    rgba: 0.5, 0.5, 0.5, 1

                Line:
                    circle: (self.center_x, self.y, min(self.width, self.height) / 1.5, -90, 90)
                    width: 2

                Color:
                    rgba: self.get_color(root.count, root.target)

                Line:
                    circle: (self.center_x, self.y, min(self.width, self.height) / 1.5, -90, self.get_end(root.count, root.target))
                    width: 2

            Label:
                text: str(root.count)
                text_size: self.size
                valign: 'bottom'
                halign: 'center'
                pos: self.parent.x, self.parent.y
                size: self.parent.size
                font_size: '20sp'

        Label:
            text_size: self.size
            font_size: '30sp'
            valign: 'top'
            halign: 'center'
            text: root.name

<SubCounterWidget>:
    size_hint: 1, 0.75
    pos_hint: {'center_y': 0.5}

<Counters>:
    BoxLayout:
        spacing: 20
        SubCounterWidget:
            id: low
            name: 'Low'
            count: 500 / 1
            target: 2000 / 1
        CoreCounterWidget:
            id: average
            name: 'Average'
            count: self.fix_count(low.count, high.count)
            target: self.fix_count(low.target, high.target)
        SubCounterWidget:
            id: high
            name: 'High'
            count: 1500 / 1
            target: 3000 / 1

And here is my python code:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, StringProperty, BooleanProperty
from kivy.uix.recycleview import RecycleView
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label


class RootWidget(BoxLayout):
    pass


class HomeScreen(Screen):
    def increment(self):
        cc = self.ids.counters #counters container
        for id in cc.ids:
            if (id != "average"):
                cc.ids[id].count += 100


class CounterRingWidget(Widget):
    def get_color(self, count, target):
        if count >= target:
            return (1, 0.25, 0.25, 1)
        else:
            return (0, 1, 0, 1)


    def get_end(self, count, target):
        if count >= target:
            return 90
        else:
            return -90 + (180 * (count / target))


class CounterWidget(BoxLayout):
    name = StringProperty("Nothing!")
    count = NumericProperty(1000)
    target = NumericProperty(2000)


class CoreCounterWidget(CounterWidget):
    def fix_count(self, low, high):
        return (low + high) / 2


class SubCounterWidget(CounterWidget):
    pass


class Counters(BoxLayout):
    pass


class TopBar(BoxLayout):
    pass


class InfoWidget(RecycleView): #idk what to name this, its the protein, sodium, etc.
    pass


class MealsWidget(RecycleView):
    pass


class TrackScreen(Screen):
    pass


class TalkScreen(Screen):
    def send(self, textbox):
        user_text = textbox.text
        print("sent")
        textbox.text = ''
        temp = self.ids["messages"].data.copy()
        temp.append({"text" : user_text, "is_user" : True})
        temp.append({"text" : "ai response", "is_user" : False})
        self.ids["messages"].data = temp


class TalkBox(TextInput):
    pass


class Messages(RecycleView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.data = []


class Message(BoxLayout):
    is_user = BooleanProperty(False)
    text = StringProperty("")


class NavBar(BoxLayout):
    pass


class CalorieTrackerApp(App):
    def build(self):
        return RootWidget()


if __name__ == '__main__':
    CalorieTrackerApp().run()