Skip to content

Commit d79cdeb

Browse files
committed
Change colour of Tk toolbar icons on dark backgrounds
Also check the background colour of Checkbuttons in the selected state
1 parent 5de27aa commit d79cdeb

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

lib/matplotlib/backends/_backend_tk.py

+18
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,24 @@ def _set_image_for_button(self, button):
652652
# Use the high-resolution (48x48 px) icon if it exists and is needed
653653
with Image.open(path_large if (size > 24 and path_large.exists())
654654
else path_regular) as im:
655+
colors = ["background", "activebackground"]
656+
if isinstance(button, tk.Checkbutton):
657+
colors.append("selectcolor")
658+
for color in colors:
659+
if button.cget(color) == "":
660+
continue
661+
# Get the color as an (r, g, b) tuple in the range from 0 to
662+
# 65535, and check if its HSV V is under 50%.
663+
if max(button.winfo_rgb(button.cget(color))) < 65535 / 2:
664+
# Change the colour of the icon to be visible against
665+
# the dark background.
666+
foreground = (255 / 65535) * np.array(
667+
button.winfo_rgb(button.cget("foreground")))
668+
image_data = np.asarray(im)
669+
black_mask = (image_data[..., :3] == 0).all(axis=-1)
670+
image_data[black_mask, :3] = foreground
671+
im = Image.fromarray(image_data, mode="RGBA")
672+
break
655673
image = ImageTk.PhotoImage(im.resize((size, size)), master=self)
656674
button.configure(image=image, height='18p', width='18p')
657675
button._ntimage = image # Prevent garbage collection.

lib/matplotlib/tests/test_backend_tk.py

+39
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,42 @@ class Toolbar(NavigationToolbar2Tk):
185185
print("success")
186186
Toolbar(fig.canvas, fig.canvas.manager.window) # This should not raise.
187187
print("success")
188+
189+
190+
@pytest.mark.backend('TkAgg', skip_on_importerror=True)
191+
@_isolated_tk_test(success_count=2)
192+
def test_embedding(): # pragma: no cover
193+
import tkinter as tk
194+
from matplotlib.backends.backend_tkagg import (
195+
FigureCanvasTkAgg, NavigationToolbar2Tk)
196+
from matplotlib.backend_bases import key_press_handler
197+
from matplotlib.figure import Figure
198+
199+
root = tk.Tk()
200+
201+
def test_figure(master):
202+
fig = Figure()
203+
ax = fig.add_subplot()
204+
ax.plot([1, 2, 3])
205+
206+
canvas = FigureCanvasTkAgg(fig, master=master)
207+
canvas.draw()
208+
canvas.mpl_connect("key_press_event", key_press_handler)
209+
canvas.get_tk_widget().pack(expand=True, fill="both")
210+
211+
toolbar = NavigationToolbar2Tk(canvas, master, pack_toolbar=False)
212+
toolbar.pack(expand=True, fill="x")
213+
214+
canvas.get_tk_widget().forget()
215+
toolbar.forget()
216+
217+
test_figure(root)
218+
print("success")
219+
220+
# Test with a dark button color. Doesn't actually check whether the icon
221+
# color becomes lighter, just that the code doesn't break.
222+
223+
root.tk_setPalette(background="sky blue", selectColor="midnight blue",
224+
foreground="white")
225+
test_figure(root)
226+
print("success")

0 commit comments

Comments
 (0)