John,
I had some questions about this resize work. Here is the code for resize
from backend_gtk.py:
def resize(self, w, h):
'set the drawing area size in pixels'
winw, winh = self.parent.parent.get_size()
tmp, tmp, myw, myh = self.allocation
padw = winw-myw
padh = winh-myh
self.parent.parent.resize(w+padw, h+padh)
I'm a little concerned about this implementation. It looks like the widget
is telling it's parent's parent to resize. Doesn't this mean that the
ability of the widget to be used as a modular component is reduced because
this code requires a certain parent child relationship?
I think it's fairly important that a widget have only very minimum
interactions with it's parent. Is there some way this could be
implemented that doesn't require the child widget to be calling methods on
the parent?
If I understand the basic premise you've outlined below, you want a resize
in the child (the drawing widget) to cause the parent window to
resize. Only the parent can figure out what it's size needs to be (since
it knows about it's margins, toolbars, etc). On the surface, it seems like
there are two ways to handling this:
1) Tell the window to resize the canvas. The window can use it's own
layout classes, etc and correctly resize itself and the canvas.
2) Tell the canvas to resize and have this trigger a window resize.
I think the first option is much cleaner. However, if that isn't possible,
I suggest that we do something like this:
- Tell the canvas to resize. It should resize itself and emit some type of
'plotCanvasResize' signal (GUI callback).
- When the window is originally constructed, it would attach a method on
the window to this signal so that we basically get the same behavior as 1)
above. Telling the canvas to resize emits the signal which calls the
window method to do the real resizing. The canvas widget never knows that
it's part of the window at all.
Of course this assumes that we have access to signal/slot (in Qt terms)
systems in the Python layer. I'd also suggest that we stay away from
calling it 'resize' since most GUI toolkits already have resize
methods/attributes that mean very specific things.
Thoughts?
Ted
> There is a new method in the figure canvas in CVS that I would like
> the maintainers of the various GUI backends to implement
>
> class FigureCanvasYourBackend
>
> def resize(self, w, h):
> """
> set the canvas size in pixels
> """
> pass
>
> This should set the canvas (not window) size and trigger a GUI resize
> event so that the window is resized accordingly. There is a reference
> implementation in backend_gtk.py. You should be able to lift the
> logic for computing the new canvas size directly from that code.
>
> Among other things, this will allow better control of the canvas size
> from a script or shell. Eg, the following works with GTKAgg in an
> interactive session:
>
> In [1]: fig = figure()
> In [2]: fig.set_figsize_inches(3,4,forward=True)
> In [3]: fig.canvas.resize(500,600)
>
> Ie, you can set the canvas size either in pixels or inches depending
> on which method you choose.
>
> Also, I added a new connect signal 'resize_event' that triggers a
> backend_bases.ResizeEvent on a canvas.resize. You should call
>
> self.resize_event()
>
> from the part of your code that handles GUI configure events (see for
> example the GTK and GTKAgg backends). Note depending on your toolkit,
> you may not want to call this from the FigureCanvas.resize method.
> Eg, in GTK* calling "canvas.resize" triggers a call to
> canvas.configure_event, which in turn sets the new figure size
> properties and once all this is done, calls canvas.resize_event.
>
> Here is some test code
>
> from pylab import figure, connect, show
> fig = figure()
> def resize(event):
> print 'resize canvas', event.width, event.height
>
> connect('resize_event', resize)
> show()
>
> Checking in lib/matplotlib/backend_bases.py;
> /cvsroot/matplotlib/matplotlib/lib/matplotlib/backend_bases.py,v <--
> backend_bases.py
> new revision: 1.69; previous revision: 1.68
>
> Thanks!
> JDH
>
>
Ted Drain Jet Propulsion Laboratory ted.drain@...
|