Making a Color Picker in Python with Kivy/KivyMD from Scratch

Making a Color Picker in Python with Kivy/KivyMD from Scratch

If you have ever opened kivy's built in colorpicker widget, I am sure you felt disappointed by how old fashioned it looks.

kivy's builtin color picker - new.PNG Today we would be creating a color picker widget, that looks more decent with kivyMD.

Creating the placeholders.

First you need three boxes, one to display the [color spectrum] (en.wikipedia.org/wiki/Spectral_color), this box is called the color slider, and it has an horziontal linear gradient of the visible colors i.e Red, Orange, Yellow, Green, Blue, Indigo, Violet and then back to Red.

custom color picker - spectrum - edit.PNG

Another box for selecting the Lightness of the color, this is also an horizontal linear gradient from very light (white) to very dark (pure value of the selected color).

custom color picker - lightness.PNG

Then lastly, a box with a vertical linear gradient for selecting the saturation of the selected color.

custom color picker - saturation.PNG

To begin with lets do imports, Obviously we need to import MDApp then we import Builder to load the kv string, next we import MDBoxLayout, Window to resize the window, Few properties we would need, Clock to do some scheduling (I would explain later), and then boundary to make sure our sliders does not goes out of the color boxes. Everything listed above is included in the kivy library :).

from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.core.window import Window
from kivy.properties import NumericProperty, BooleanProperty
from kivy.clock import Clock
from kivy.utils import boundary

Resizing the window.

Window.size = (500, 300)

Now we create the root widget, that would contain all the color boxes, with three properties.

class CustomColorPicker(MDBoxLayout):
    hue = NumericProperty(0)
    saturation = NumericProperty(1)
    value = NumericProperty(1)

Setting saturation and value to 1 by default is optional, but it makes sense to have the colors at full brightness and saturation.

class SpectrumBox(MDBoxLayout):
    pass

class LightnessBox(MDBoxLayout):
    pass

class SaturationBox(MDBoxLayout):
    pass

class Test(MDApp):
        def build(self):
            return CustomColorPicker()
Test().run()