mirror of
https://github.com/python/cpython
synced 2024-09-16 03:10:05 +00:00
bpo-33289: Return RGB triplet of ints instead of floats from tkinter.colorchooser (GH-6578)
This commit is contained in:
parent
805ede8ae8
commit
6713e869c4
|
@ -1185,8 +1185,7 @@ def winfo_reqwidth(self):
|
||||||
self.tk.call('winfo', 'reqwidth', self._w))
|
self.tk.call('winfo', 'reqwidth', self._w))
|
||||||
|
|
||||||
def winfo_rgb(self, color):
|
def winfo_rgb(self, color):
|
||||||
"""Return tuple of decimal values for red, green, blue for
|
"""Return a tuple of integer RGB values in range(65536) for color in this widget."""
|
||||||
COLOR in this widget."""
|
|
||||||
return self._getints(
|
return self._getints(
|
||||||
self.tk.call('winfo', 'rgb', self._w, color))
|
self.tk.call('winfo', 'rgb', self._w, color))
|
||||||
|
|
||||||
|
|
|
@ -8,57 +8,69 @@
|
||||||
# fixed initialcolor handling in August 1998
|
# 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
|
from tkinter.commondialog import Dialog
|
||||||
|
|
||||||
__all__ = ["Chooser", "askcolor"]
|
__all__ = ["Chooser", "askcolor"]
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# color chooser class
|
|
||||||
|
|
||||||
class Chooser(Dialog):
|
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"
|
command = "tk_chooseColor"
|
||||||
|
|
||||||
def _fixoptions(self):
|
def _fixoptions(self):
|
||||||
|
"""Ensure initialcolor is a tk color string.
|
||||||
|
|
||||||
|
Convert initialcolor from a RGB triplet to a color string.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
# make sure initialcolor is a tk color string
|
|
||||||
color = self.options["initialcolor"]
|
color = self.options["initialcolor"]
|
||||||
if isinstance(color, tuple):
|
if isinstance(color, tuple):
|
||||||
# assume an RGB triplet
|
# Assume an RGB triplet.
|
||||||
self.options["initialcolor"] = "#%02x%02x%02x" % color
|
self.options["initialcolor"] = "#%02x%02x%02x" % color
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _fixresult(self, widget, result):
|
def _fixresult(self, widget, result):
|
||||||
# result can be somethings: an empty tuple, an empty string or
|
"""Adjust result returned from call to tk_chooseColor.
|
||||||
# a Tcl_Obj, so this somewhat weird check handles that
|
|
||||||
if not result or not str(result):
|
|
||||||
return None, None # canceled
|
|
||||||
|
|
||||||
# to simplify application code, the color chooser returns
|
Return both an RGB tuple of ints in the range (0, 255) and the
|
||||||
# an RGB tuple together with the Tk color string
|
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
|
||||||
|
|
||||||
|
# To simplify application code, the color chooser returns
|
||||||
|
# an RGB tuple together with the Tk color string.
|
||||||
r, g, b = widget.winfo_rgb(result)
|
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
|
# convenience stuff
|
||||||
|
|
||||||
def askcolor(color = None, **options):
|
def askcolor(color=None, **options):
|
||||||
"Ask for a color"
|
"""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:
|
if color:
|
||||||
options = options.copy()
|
options = options.copy()
|
||||||
|
|
|
@ -1,13 +1,44 @@
|
||||||
import unittest
|
import unittest
|
||||||
import tkinter
|
import tkinter
|
||||||
from test.support import requires, run_unittest, swap_attr
|
from test.support import requires, run_unittest, swap_attr
|
||||||
from tkinter.test.support import AbstractDefaultRootTest
|
from tkinter.test.support import AbstractDefaultRootTest, AbstractTkTest
|
||||||
from tkinter.commondialog import Dialog
|
from tkinter import colorchooser
|
||||||
from tkinter.colorchooser import askcolor
|
from tkinter.colorchooser import askcolor
|
||||||
|
from tkinter.commondialog import Dialog
|
||||||
|
|
||||||
requires('gui')
|
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'))
|
||||||
|
|
||||||
|
|
||||||
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
|
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
|
||||||
|
|
||||||
def test_askcolor(self):
|
def test_askcolor(self):
|
||||||
|
@ -33,7 +64,7 @@ def test_callback(dialog, master):
|
||||||
self.assertRaises(RuntimeError, askcolor)
|
self.assertRaises(RuntimeError, askcolor)
|
||||||
|
|
||||||
|
|
||||||
tests_gui = (DefaultRootTest,)
|
tests_gui = (ChooserTest, DefaultRootTest,)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
run_unittest(*tests_gui)
|
run_unittest(*tests_gui)
|
||||||
|
|
|
@ -192,6 +192,26 @@ def test_clipboard_astral(self):
|
||||||
with self.assertRaises(tkinter.TclError):
|
with self.assertRaises(tkinter.TclError):
|
||||||
root.clipboard_get()
|
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):
|
def test_event_repr_defaults(self):
|
||||||
e = tkinter.Event()
|
e = tkinter.Event()
|
||||||
e.serial = 12345
|
e.serial = 12345
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Correct call to :mod:`tkinter.colorchooser` to return RGB triplet of ints
|
||||||
|
instead of floats. Patch by Cheryl Sabella.
|
Loading…
Reference in a new issue