Amir Taaki wrote:
Thank you so very much for your reply - it was most helpful.
You're quite welcome.
Yes I had looked at Matplotlib, SciPy and PyPlotter. wxPyPlot looks
promising but it doesn't look like its made for graph editing.
No, but it's fairly simple, why write the whole thing when all you need to write is the editing part? Even if you don't' use it, you can get ideas from it.
On the other hand, the float canvas sounds most promising, but I can't
seem to find any working links and the wxPython floatcanvas demo
throws with
genjix@amir /usr/share/doc/wxPython-2.4.2.4/demo $ python demo.py
Traceback (most recent call last):
File "/usr/share/doc/wxPython-2.4.2.4/demo/Main.py", line 528, in OnSelChanged
self.RunDemo(itemText)
File "/usr/share/doc/wxPython-2.4.2.4/demo/Main.py", line 556, in RunDemo
module = __import__(itemText, globals())
File "/usr/share/doc/wxPython-2.4.2.4/demo/FloatCanvas.py", line 39, in ?
from wxPython.lib import floatcanvas
File "/usr/lib/python2.4/site-packages/wx-2.6-gtk2-ansi/wxPython/lib/floatcanvas.py",
line 9, in ?
Circle = wx.lib.floatcanvas.Circle
AttributeError: 'module' object has no attribute 'Circle'
genjix@amir /usr/share/doc/wxPython-2.4.2.4/demo $
wxPython 2.4.2.4 is pretty old. I could have sworn FloatCanvas worked in that version, but who knows? I do have the last version that worked with 2.4.2 archived at work, if you want me to send it to you.
You could also comment out the section of code that's throwing that error and see if you can get it to run. However, I have added a LOT to FloatCanvas since that version. I don't remember exactly the state of the event binding, but I'm pretty sure it's improved.
2.4.2 is a pretty old version. You really, really want to upgrade!
About the import wx, I don't really see why the C++ wxWidgets library
doesn't use namespaces yet the python version has to (and the wxPython
demo hasn't even been updated to take this change into consideration
when all it would take, would be a s/wx/wx\./).
The demo has been updated in newer versions.
Name spaces are a inherent part of Python -- they are tacked on, and for some odd reason, little used in C++. When the switch was made for wxPython, the wxWidgets folks were talking about using name spaces for C++ also, but backward compatibility won out.
I know calling OnPaint is a problem, but what should I be doing
instead? How force a redraw (I don't just want to redraw the buffer).
If you are changing the Buffer, you can then blit it to the screen yourself with a wxClientDC. Also, you should NEVER call OnPaint yourself, but there are times when a Refresh() and/or Update is called for.
Here's the key, however. When you are drawing something that is not intended to be persistent, like the selection box (some call it a rubber band box), you don't need to draw to the buffer at all. You can just draw to the screen. Take a look in the floatcanvas code to see how this is done. Here's some code cut out of FloatCanvas and trimmed for simplicity, that should give you the idea:
def LeftDownEvent(self,event):
self.StartRBBox = array( event.GetPosition() )
self.PrevRBBox = None
self.CaptureMouse()
def LeftUpEvent(self,event):
if self.HasCapture():
self.ReleaseMouse()
def MotionEvent(self,event):
if ( event.Dragging() and
event.LeftIsDown() and
not (self.StartRBBox is None):
xy0 = self.StartRBBox
xy1 = array( event.GetPosition() )
wh = xy1 - xy0
dc = wx.ClientDC(self)
dc.BeginDrawing()
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.XOR)
if self.PrevRBBox:
## This restores the screen to the original image.
dc.DrawRectanglePointSize(*self.PrevRBBox)
self.PrevRBBox = ( xy0, wh )
dc.DrawRectanglePointSize( *self.PrevRBBox )
dc.EndDrawing()
In fact, in my FloatCanvas based polygon editor (ask me and I can send it, but it's 2.6 only), I do a similar thing while moving points int eh polygon. I draw directly to the screen to show the moving segments and only update the buffered image after the Mouse is released.
Maybe I should use OpenGL? (I am using OpenGL in my app anyway, so
maybe I could benefit from the hw accel)
I'm not sure you'd get any benefit unless you are doing something 3-d, but if you're using it anyway, and you're comfortable with it, it might make sense.
if self.HasCapture():
self.ReleaseMouse()
Is this sufficient? or should I be doing
That should do it.
self.ReleaseMouse()
It should be, but I think you get an error if you call this when the Mouse isn't captured.
Thank you for taking your time to reply.
Good luck. If you can move to 2.6.*, ask me for the latest FloatCanvas, it should make this pretty simple.
-Chris
···
--
Christopher Barker, Ph.D.
Oceanographer
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov