Skip to content

Commit

Permalink
[3.9] bpo-33289: Return RGB triplet of ints instead of floats from tk…
Browse files Browse the repository at this point in the history
…inter.colorchooser (GH-6578). (GH-24318)

(cherry picked from commit 6713e86)

Co-authored-by: Cheryl Sabella <cheryl.sabella@gmail.com>
(cherry picked from commit 3d5434d)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
miss-islington and serhiy-storchaka committed Jan 25, 2021
1 parent 63ebba0 commit 96bcf6f
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 26 deletions.
3 changes: 1 addition & 2 deletions Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1160,8 +1160,7 @@ def winfo_reqwidth(self):
self.tk.call('winfo', 'reqwidth', self._w))

def winfo_rgb(self, color):
"""Return tuple of decimal values for red, green, blue for
COLOR in this widget."""
"""Return a tuple of integer RGB values in range(65536) for color in this widget."""
return self._getints(
self.tk.call('winfo', 'rgb', self._w, color))

Expand Down
60 changes: 36 additions & 24 deletions Lib/tkinter/colorchooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,67 @@
# fixed initialcolor handling in August 1998
#

#
# options (all have default values):
#
# - initialcolor: color to mark as selected when dialog is displayed
# (given as an RGB triplet or a Tk color string)
#
# - parent: which window to place the dialog on top of
#
# - title: dialog title
#

from tkinter.commondialog import Dialog


#
# color chooser class

class Chooser(Dialog):
"Ask for a color"
"""Create a dialog for the tk_chooseColor command.
Args:
master: The master widget for this dialog. If not provided,
defaults to options['parent'] (if defined).
options: Dictionary of options for the tk_chooseColor call.
initialcolor: Specifies the selected color when the
dialog is first displayed. This can be a tk color
string or a 3-tuple of ints in the range (0, 255)
for an RGB triplet.
parent: The parent window of the color dialog. The
color dialog is displayed on top of this.
title: A string for the title of the dialog box.
"""

command = "tk_chooseColor"

def _fixoptions(self):
"""Ensure initialcolor is a tk color string.
Convert initialcolor from a RGB triplet to a color string.
"""
try:
# make sure initialcolor is a tk color string
color = self.options["initialcolor"]
if isinstance(color, tuple):
# assume an RGB triplet
# Assume an RGB triplet.
self.options["initialcolor"] = "#%02x%02x%02x" % color
except KeyError:
pass

def _fixresult(self, widget, result):
# result can be somethings: an empty tuple, an empty string or
# a Tcl_Obj, so this somewhat weird check handles that
"""Adjust result returned from call to tk_chooseColor.
Return both an RGB tuple of ints in the range (0, 255) and the
tk color string in the form #rrggbb.
"""
# Result can be many things: an empty tuple, an empty string, or
# a _tkinter.Tcl_Obj, so this somewhat weird check handles that.
if not result or not str(result):
return None, None # canceled
return None, None # canceled

# to simplify application code, the color chooser returns
# an RGB tuple together with the Tk color string
# To simplify application code, the color chooser returns
# an RGB tuple together with the Tk color string.
r, g, b = widget.winfo_rgb(result)
return (r/256, g/256, b/256), str(result)
return (r//256, g//256, b//256), str(result)


#
# convenience stuff

def askcolor(color = None, **options):
"Ask for a color"
def askcolor(color=None, **options):
"""Display dialog window for selection of a color.
Convenience wrapper for the Chooser class. Displays the color
chooser dialog with color as the initial value.
"""

if color:
options = options.copy()
Expand Down
43 changes: 43 additions & 0 deletions Lib/tkinter/test/test_tkinter/test_colorchooser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import unittest
import tkinter
from test.support import requires, run_unittest, swap_attr
from tkinter.test.support import AbstractTkTest
from tkinter import colorchooser

requires('gui')


class ChooserTest(AbstractTkTest, unittest.TestCase):

@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
cls.cc = colorchooser.Chooser(initialcolor='dark blue slate')

def test_fixoptions(self):
cc = self.cc
cc._fixoptions()
self.assertEqual(cc.options['initialcolor'], 'dark blue slate')

cc.options['initialcolor'] = '#D2D269691E1E'
cc._fixoptions()
self.assertEqual(cc.options['initialcolor'], '#D2D269691E1E')

cc.options['initialcolor'] = (210, 105, 30)
cc._fixoptions()
self.assertEqual(cc.options['initialcolor'], '#d2691e')

def test_fixresult(self):
cc = self.cc
self.assertEqual(cc._fixresult(self.root, ()), (None, None))
self.assertEqual(cc._fixresult(self.root, ''), (None, None))
self.assertEqual(cc._fixresult(self.root, 'chocolate'),
((210, 105, 30), 'chocolate'))
self.assertEqual(cc._fixresult(self.root, '#4a3c8c'),
((74, 60, 140), '#4a3c8c'))


tests_gui = (ChooserTest,)

if __name__ == "__main__":
run_unittest(*tests_gui)
20 changes: 20 additions & 0 deletions Lib/tkinter/test/test_tkinter/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,26 @@ def test_clipboard_astral(self):
with self.assertRaises(tkinter.TclError):
root.clipboard_get()

def test_winfo_rgb(self):
root = self.root
rgb = root.winfo_rgb

# Color name.
self.assertEqual(rgb('red'), (65535, 0, 0))
self.assertEqual(rgb('dark slate blue'), (18504, 15677, 35723))
# #RGB - extends each 4-bit hex value to be 16-bit.
self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF))
# #RRGGBB - extends each 8-bit hex value to be 16-bit.
self.assertEqual(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))
# #RRRRGGGGBBBB
self.assertEqual(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))
# Invalid string.
with self.assertRaises(tkinter.TclError):
rgb('#123456789a')
# RGB triplet is invalid input.
with self.assertRaises(tkinter.TclError):
rgb((111, 78, 55))

def test_event_repr_defaults(self):
e = tkinter.Event()
e.serial = 12345
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Correct call to :mod:`tkinter.colorchooser` to return RGB triplet of ints
instead of floats. Patch by Cheryl Sabella.

0 comments on commit 96bcf6f

Please sign in to comment.