The following program was written to understand how two different color systems related to each other, RGB and HSV. The recipe could be better written and extended further to support other color systems in addition to the two it already uses, but it is a simple example of how one might go about to understand what others speak of when talking about color. The GUI is simple to use and responsive, and the code is a good demonstration of what may need to be written to produce a demonstration such as this one.
If you have suggestions or would like to vote this recipe down, please provide an explanation of the problem along with a solution that you would propose and implement to improve upon what is presented.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | import tkinter.ttk
import colorsys
class ColorStudy(tkinter.ttk.Frame):
LABEL = dict(width=9, anchor=tkinter.CENTER)
SCALE = dict(orient=tkinter.HORIZONTAL, length=256, from_=0.0, to=1.0)
VALUE = dict(text='0.0', width=5, relief=tkinter.GROOVE)
BYTE = dict(text='00', width=3, relief=tkinter.GROOVE,
anchor=tkinter.CENTER)
PADDING = dict(padx=2, pady=2)
@classmethod
def main(cls):
tkinter.NoDefaultRoot()
root = tkinter.Tk()
root.title('Color Study')
root.resizable(False, False)
view = cls(root)
view.grid(row=0, column=0)
root.mainloop()
def __init__(self, master):
super().__init__(master)
# Create all the widgets.
self.rgb_scales = self.create_rgb_scales()
self.hsv_scales = self.create_hsv_scales()
self.color_area = self.create_color_area()
# Place them on the grid.
self.rgb_scales.grid(row=0, column=0)
self.hsv_scales.grid(row=1, column=0)
self.color_area.grid(row=2, column=0, sticky=tkinter.EW)
def create_rgb_scales(self):
rgb_scales = tkinter.ttk.Labelframe(self, text='RGB Scales')
# Create the inner widget.
self.r_label = tkinter.ttk.Label(rgb_scales, text='Red', **self.LABEL)
self.g_label = tkinter.ttk.Label(rgb_scales, text='Green', **self.LABEL)
self.b_label = tkinter.ttk.Label(rgb_scales, text='Blue', **self.LABEL)
self.r_scale = tkinter.ttk.Scale(rgb_scales, command=self.rgb_updated,
**self.SCALE)
self.g_scale = tkinter.ttk.Scale(rgb_scales, command=self.rgb_updated,
**self.SCALE)
self.b_scale = tkinter.ttk.Scale(rgb_scales, command=self.rgb_updated,
**self.SCALE)
self.r_value = tkinter.ttk.Label(rgb_scales, **self.VALUE)
self.g_value = tkinter.ttk.Label(rgb_scales, **self.VALUE)
self.b_value = tkinter.ttk.Label(rgb_scales, **self.VALUE)
self.r_byte = tkinter.ttk.Label(rgb_scales, **self.BYTE)
self.g_byte = tkinter.ttk.Label(rgb_scales, **self.BYTE)
self.b_byte = tkinter.ttk.Label(rgb_scales, **self.BYTE)
# Place widgets on grid.
self.r_label.grid(row=0, column=0, **self.PADDING)
self.g_label.grid(row=1, column=0, **self.PADDING)
self.b_label.grid(row=2, column=0, **self.PADDING)
self.r_scale.grid(row=0, column=1, **self.PADDING)
self.g_scale.grid(row=1, column=1, **self.PADDING)
self.b_scale.grid(row=2, column=1, **self.PADDING)
self.r_value.grid(row=0, column=2, **self.PADDING)
self.g_value.grid(row=1, column=2, **self.PADDING)
self.b_value.grid(row=2, column=2, **self.PADDING)
self.r_byte.grid(row=0, column=3, **self.PADDING)
self.g_byte.grid(row=1, column=3, **self.PADDING)
self.b_byte.grid(row=2, column=3, **self.PADDING)
# Return the label frame.
return rgb_scales
def create_hsv_scales(self):
hsv_scales = tkinter.ttk.Labelframe(self, text='HSV Scales')
# Create the inner widget.
self.h_label = tkinter.ttk.Label(hsv_scales, text='Hue', **self.LABEL)
self.s_label = tkinter.ttk.Label(hsv_scales, text='Saturation',
**self.LABEL)
self.v_label = tkinter.ttk.Label(hsv_scales, text='Value', **self.LABEL)
self.h_scale = tkinter.ttk.Scale(hsv_scales, command=self.hsv_updated,
**self.SCALE)
self.s_scale = tkinter.ttk.Scale(hsv_scales, command=self.hsv_updated,
**self.SCALE)
self.v_scale = tkinter.ttk.Scale(hsv_scales, command=self.hsv_updated,
**self.SCALE)
self.h_value = tkinter.ttk.Label(hsv_scales, **self.VALUE)
self.s_value = tkinter.ttk.Label(hsv_scales, **self.VALUE)
self.v_value = tkinter.ttk.Label(hsv_scales, **self.VALUE)
self.h_byte = tkinter.ttk.Label(hsv_scales, **self.BYTE)
self.s_byte = tkinter.ttk.Label(hsv_scales, **self.BYTE)
self.v_byte = tkinter.ttk.Label(hsv_scales, **self.BYTE)
# Place widgets on grid.
self.h_label.grid(row=0, column=0, **self.PADDING)
self.s_label.grid(row=1, column=0, **self.PADDING)
self.v_label.grid(row=2, column=0, **self.PADDING)
self.h_scale.grid(row=0, column=1, **self.PADDING)
self.s_scale.grid(row=1, column=1, **self.PADDING)
self.v_scale.grid(row=2, column=1, **self.PADDING)
self.h_value.grid(row=0, column=2, **self.PADDING)
self.s_value.grid(row=1, column=2, **self.PADDING)
self.v_value.grid(row=2, column=2, **self.PADDING)
self.h_byte.grid(row=0, column=3, **self.PADDING)
self.s_byte.grid(row=1, column=3, **self.PADDING)
self.v_byte.grid(row=2, column=3, **self.PADDING)
# Return the label frame.
return hsv_scales
def create_color_area(self):
color_area = tkinter.ttk.Labelframe(self, text='Color Sample')
self.canvas = tkinter.Canvas(color_area, height=70,
background='#000000')
self.canvas.grid(row=0, column=0)
return color_area
def rgb_updated(self, value):
r = self.r_scale['value']
g = self.g_scale['value']
b = self.b_scale['value']
self.update_rgb(r, g, b)
h, s, v = colorsys.rgb_to_hsv(r, g, b)
self.update_hsv(h, s, v)
self.update_color_area()
def hsv_updated(self, value):
h = self.h_scale['value']
s = self.s_scale['value']
v = self.v_scale['value']
self.update_hsv(h, s, v)
r, g, b = colorsys.hsv_to_rgb(h, s, v)
self.update_rgb(r, g, b)
self.update_color_area()
def update_rgb(self, r, g, b):
self.r_scale['value'] = r
self.g_scale['value'] = g
self.b_scale['value'] = b
self.r_value['text'] = str(r)[:5]
self.g_value['text'] = str(g)[:5]
self.b_value['text'] = str(b)[:5]
self.r_byte['text'] = '{:02X}'.format(round(r * 255))
self.g_byte['text'] = '{:02X}'.format(round(g * 255))
self.b_byte['text'] = '{:02X}'.format(round(b * 255))
def update_hsv(self, h, s, v):
self.h_scale['value'] = h
self.s_scale['value'] = s
self.v_scale['value'] = v
self.h_value['text'] = str(h)[:5]
self.s_value['text'] = str(s)[:5]
self.v_value['text'] = str(v)[:5]
self.h_byte['text'] = '{:02X}'.format(round(h * 255))
self.s_byte['text'] = '{:02X}'.format(round(s * 255))
self.v_byte['text'] = '{:02X}'.format(round(v * 255))
def update_color_area(self):
color = '#{}{}{}'.format(self.r_byte['text'],
self.g_byte['text'],
self.b_byte['text'])
self.canvas['background'] = color
if __name__ == '__main__':
ColorStudy.main()
|
Using Python 2.73 it does not work! Error at line 24: super().__init__(master), etc