GUI icon in Tkinter #897

Merged
merged 6 commits into from Aug 1, 2012
@@ -359,15 +359,17 @@ def __init__(self, canvas, num):
self.window = Gtk.Window()
self.set_window_title("Figure %d" % num)
- if (window_icon):
- try:
- self.window.set_icon_from_file(window_icon)
- except:
- # some versions of gtk throw a glib.GError but not
- # all, so I am not sure how to catch it. I am unhappy
- # diong a blanket catch here, but an not sure what a
- # better way is - JDH
- verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
+ try:
+ self.window.set_icon_from_file(window_icon)
+ except (SystemExit, KeyboardInterrupt):
+ # re-raise exit type Exceptions
+ raise
+ except:
+ # some versions of gtk throw a glib.GError but not
+ # all, so I am not sure how to catch it. I am unhappy
+ # doing a blanket catch here, but am not sure what a
+ # better way is - JDH
+ verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
self.vbox = Gtk.Box()
self.vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
@@ -562,12 +564,15 @@ def configure_subplots(self, button):
window = Gtk.Window()
- if (window_icon):
- try: window.set_icon_from_file(window_icon)
- except:
- # we presumably already logged a message on the
- # failure of the main plot, don't keep reporting
- pass
+ try:
+ window.set_icon_from_file(window_icon)
+ except (SystemExit, KeyboardInterrupt):
+ # re-raise exit type Exceptions
+ raise
+ except:
+ # we presumably already logged a message on the
+ # failure of the main plot, don't keep reporting
+ pass
window.set_title("Subplot Configuration Tool")
window.set_default_size(w, h)
vbox = Gtk.Box()
@@ -963,7 +968,6 @@ def get_active_line(self):
line = self.lines[ind]
return line
-
def get_active_linestyle(self):
'get the active lineinestyle'
ind = self.cbox_linestyles.get_active()
@@ -997,8 +1001,6 @@ def _update(self):
line.figure.canvas.draw()
-
-
def on_combobox_lineprops_changed(self, item):
'update the widgets from the active line'
if not self._inited: return
@@ -1044,17 +1046,14 @@ def on_dialog_lineprops_okbutton_clicked(self, button):
def on_dialog_lineprops_cancelbutton_clicked(self, button):
self.dlg.hide()
-# set icon used when windows are minimized
-try:
@WeatherGod

WeatherGod May 24, 2012

Member

why remove this exception handling? At the very least we could use the verbose.report() there to provide us information and then re-raise (or maybe add a message to the exception and let it bubble up?)

@pelson

pelson May 24, 2012

Member

The comment needs removing, as far as I can see, this try block will never fail.

@mdboom

mdboom May 24, 2012

Owner

I actually agree that this exception handling is unnecessary -- it really shouldn't fail here, unless something is seriously wrong. This is different from the try/excepts above where if the icon can't be set we should continue along without an icon.

- if sys.platform == 'win32':
- icon_filename = 'matplotlib.png'
- else:
- icon_filename = 'matplotlib.svg'
- window_icon = os.path.join(rcParams['datapath'], 'images', icon_filename)
-except:
- window_icon = None
- verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
+# Define the file to use as the GTk icon
+if sys.platform == 'win32':
+ icon_filename = 'matplotlib.png'
+else:
+ icon_filename = 'matplotlib.svg'
+window_icon = os.path.join(matplotlib.rcParams['datapath'], 'images', icon_filename)
+
def error_msg_gtk(msg, parent=None):
if parent is not None: # find the toplevel Gtk.Window
@@ -78,6 +78,23 @@ def new_figure_manager(num, *args, **kwargs):
FigureClass = kwargs.pop('FigureClass', Figure)
figure = FigureClass(*args, **kwargs)
window = Tk.Tk()
+
+ if Tk.TkVersion >= 8.5:
+ # put a mpl icon on the window rather than the default tk icon. Tkinter
+ # doesn't allow colour icons on linux systems, but tk >=8.5 has a iconphoto
+ # command which we call directly. Source:
+ # http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html
+ icon_fname = os.path.join(rcParams['datapath'], 'images', 'matplotlib.gif')
@mdboom

mdboom May 24, 2012

Owner

It looks like matplotlib.gif didn't get committed. I tried changing this to .png -- it appears that Tkinter doesn't support png, so we'll need to include a gif version of the regular matplotlib icon.

+ icon_img = Tk.PhotoImage(file=icon_fname)
+ try:
+ window.tk.call('wm', 'iconphoto', window._w, icon_img)
+ except (SystemExit, KeyboardInterrupt):
+ # re-raise exit type Exceptions
+ raise
+ except:
+ # log the failure, but carry on
+ verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
+
canvas = FigureCanvasTkAgg(figure, master=window)
figManager = FigureManagerTkAgg(canvas, num, window)
if matplotlib.is_interactive():
@@ -1,8 +1,5 @@
from __future__ import division, print_function
"""
-
- backend_wx.py
-
A wxPython backend for matplotlib, based (very heavily) on
backend_template.py and backend_gtk.py
@@ -18,14 +15,17 @@
"""
-cvs_id = '$Id$'
+import sys
+import os
+import os.path
+import math
+import StringIO
+import weakref
+import warnings
-
-import sys, os, os.path, math, StringIO, weakref, warnings
import numpy as np
-
# Debugging settings here...
# Debug level set here. If the debug level is less than 5, information
# messages (progressively more info for lower value) are printed. In addition,
@@ -188,7 +188,6 @@ def __init__(self, parent, *args, **kwargs):
# Unbinding causes Wx to stop for some reason. Disabling for now.
# def __del__(self):
-# import wx
# TimerBase.__del__(self)
# self.parent.Bind(wx.EVT_TIMER, None, self._timer)
@@ -410,7 +409,6 @@ def get_gc(self):
assert self.gc != None, "gc must be defined"
return self.gc
-
def get_wx_font(self, s, prop):
"""
Return a wx font. Cache instances in a font dictionary for
@@ -448,14 +446,14 @@ def get_wx_font(self, s, prop):
return font
-
def points_to_pixels(self, points):
"""
convert point measures to pixes using dpi and the pixels per
inch of the display
"""
return points*(PIXELS_PER_INCH/72.0*self.dpi/72.0)
+
class GraphicsContextWx(GraphicsContextBase):
"""
The graphics context provides the color, line styles, etc...
@@ -627,6 +625,7 @@ def get_wxcolour(self, color):
a *= 255
return wx.Colour(red=int(r), green=int(g), blue=int(b), alpha=int(a))
+
class FigureCanvasWx(FigureCanvasBase, wx.Panel):
"""
The FigureCanvas contains the figure and does event handling.
@@ -1421,7 +1420,7 @@ def _create_wx_app():
# retain a reference to the app object so it does not get garbage
# collected and cause segmentation faults
_create_wx_app.theWxApp = wxapp
-
+
def draw_if_interactive():
"""
@@ -1512,6 +1511,15 @@ def __init__(self, num, fig):
self.Fit()
self.canvas.SetMinSize((2, 2))
+
+ # give the window a matplotlib icon rather than the stock one.
+ # This is not currently working on Linux and is untested elsewhere.
+ #icon_path = os.path.join(matplotlib.rcParams['datapath'],
+ # 'images', 'matplotlib.png')
+ #icon = wx.IconFromBitmap(wx.Bitmap(icon_path))
+ # for xpm type icons try:
+ #icon = wx.Icon(icon_path, wx.BITMAP_TYPE_XPM)
+ #self.SetIcon(icon)
self.figmgr = FigureManagerWx(self.canvas, num, self)
@@ -1559,15 +1567,14 @@ def Destroy(self, *args, **kwargs):
wxapp.Yield()
return True
+
class FigureManagerWx(FigureManagerBase):
"""
This class contains the FigureCanvas and GUI frame
It is instantiated by GcfWx whenever a new figure is created. GcfWx is
responsible for managing multiple instances of FigureManagerWx.
- NB: FigureManagerBase is found in _pylab_helpers
-
public attrs
canvas - a FigureCanvasWx(wx.Panel) instance
@@ -1599,7 +1606,6 @@ def destroy(self, *args):
DEBUG_MSG("destroy()", 1, self)
self.frame.Destroy()
#if self.tb is not None: self.tb.Destroy()
- import wx
@pelson

pelson May 24, 2012

Member

Already imported on line 67.

#wx.GetApp().ProcessIdle()
wx.WakeUpIdle()
@@ -1939,11 +1945,6 @@ def set_history_buttons(self):
class NavigationToolbarWx(wx.ToolBar):
def __init__(self, canvas, can_kill=False):
- """
- figure is the Figure instance that the toolboar controls
-
- win, if not None, is the wxWindow the Figure is embedded in
- """
@pelson

pelson May 24, 2012

Member

Looks like it was for an older interface or was a copy&paste error as it doesn't apply to this class.

wx.ToolBar.__init__(self, canvas.GetParent(), -1)
DEBUG_MSG("__init__()", 1, self)
self.canvas = canvas
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -98,6 +98,7 @@
'mpl-data/fonts/ttf/RELEASENOTES.TXT',
'mpl-data/images/*.xpm',
'mpl-data/images/*.svg',
+ 'mpl-data/images/*.gif',
'mpl-data/images/*.png',
'mpl-data/images/*.ppm',
'mpl-data/example/*.npy',