[fc] Graphical Hierarchy Tree in wxPython
Christopher Barker
Chris.Barker at noaa.gov
Mon Jul 16 16:31:46 PDT 2007
Astan Chee wrote:
> So I've finished modifying the wxDragImage class to support what I =
> wanted to do as mentioned above.
Your code wouldn't run for me on OS-X. It turns out that you can't call =
DC.Clear() on a MemoryDC until after the Bitmap is Selected into it, =
which makes sense. While I was making that fix, I had to change the =
order of calling:
dc =3D wx.MemoryDC()
dc.Clear()
dc.SelectObject(bmp)
to:
dc =3D wx.MemoryDC()
dc.SelectObject(bmp)
dc.Clear()
in a LOT of places, which says to me that you need some re-factoring -- =
the DRY (Don't Repeat Yourself) is a good one to follow.
I also found in SetSelected and SetUnSelected, the lines:
self.bmp =3D wx.EmptyBitmap(self.size.GetWidth(), =
self.size.GetHeight())
memDC =3D wx.MemoryDC()
memDC.SelectObject(self.bmp)
memDC.Clear()
memDC.SetTextForeground(wx.RED)
memDC.SetFont(font)
memDC.DrawText(self.text, 0, 0)
memDC.SelectObject(wx.NullBitmap)
mask =3D wx.Mask(self.bmp, bg_colour)
self.bmp.SetMask(mask)
dc.Blit(self.pos.x, self.pos.y,
self.bmp.GetWidth(), self.bmp.GetHeight(),
memDC, 0, 0, op, True)
and got an error with the Blit() call: you can't do:
memDC.SelectObject(wx.NullBitmap)
Then expect to do the Blit with that DC! However, there may be a reason =
for that line -- but it can't go there in that way.
Also, the code in those two methods is very similar -- again DRY!
Then I got:
Traceback (most recent call last):
File "./wxDragImage.py", line 688, in OnLeftUp
self.dragShape.line.Draw(dc)
File "./wxDragImage.py", line 37, in Draw
memDC, 0, 0, op, True)
File =
"//Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-pack=
ages/wx-2.8-mac-unicode/wx/_gdi.py", =
line 3373, in Blit
return _gdi_.DC_Blit(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "Ok()" failed at =
/BUILD/wxPython-src-2.8.4.0/src/common/dcgraph.cpp(733) in DoBlit(): =
wxGCDC(cg)::DoBlit - invalid DC
I'm not sure what that's about yet, so I don't have your code fully =
running.
I see this (in Expand, but probably I other places):
if self.bmp.Ok():
bg_colour =3D wx.Colour(0, 0, 0)
font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
self.bmp =3D wx.EmptyBitmap(self.size.GetWidth(), self.size.GetHeight(=
))
looks like a potential error: Why check if the bmp is Ok() if you're =
going to make a new one anyway?
I worked with the wx. namespace version that someone posted to the =
wxPython list -- I found a few more spots to fix.
I also got rid of the dependency on the Demo "Run.py" script, creating a =
simple wx.App instead.
> I didn't use FloatCanvas for this =
> because I wanted to display text
FloatCanvas handles Text just fine.
> also I seemed to like the wxDragImage =
> better. As for zooming, I think scrolling is the same thing.
no, it's not -- you may not need zooming, but it would let you see more =
of less of the tree as you like.
Anyway, all the problems I describe above point out why FloatCanvas is =
so nifty -- all that working nwioth bitmaps and wxDCs is a pain in teh =
*&&^*. That's why I wrote FloatCanvas -- I had to figure it all out in =
there, and now it just works for you.
Also, maybe there is still something wrong with your code on OS-X, but =
it is intensely slow when re-sizing or really just about any interaction.
> The code =
> works by creating a hierarchy from dictionaries that may contain other =
> (deeper) dictionaries.
and also lists of string -- I found it a bit tricky to parse out the =
tree, as it wasn't internally consistent.
Anyway, I've make a stab at doing it with FloatCanvas. You tree layout =
code was pretty enmeshed with the DragObject code, so rather than =
duplicating it, I started from scratch. As you well know, laying out a =
tree like that is far from trivial, and I've not done anything =
brilliant, but it works OK. You do need to know the depth of the tree =
before hand to make it work, though.
Anyway, that's not the point. What I have now is a FloatCanvas based =
version that zooms, scrolled, lets you drag the nodes around, and is =
pretty darn snappy.
It needs some refactoring before it's expanded much - the tree layout =
code should be a separate module, You definately don't want hard coded =
data, and you'll probably want a niftier DrawObject to represent your =
nodes, etc.
Enclosed is the code and a screen shot. It should work with the =
FloatCanvas shipped with wxPython 2.8.4
-Chris
PS: not one reference to a Bitmap, MemoryDC, Blit, etc.
-- =
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker at noaa.gov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Screenshot.png
Type: image/png
Size: 46130 bytes
Desc: not available
Url : http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/20070=
716/b0112c80/Screenshot.png
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Tree.py
Type: text/x-python
Size: 9704 bytes
Desc: not available
Url : http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/20070=
716/b0112c80/Tree.py
More information about the wxpython-users
mailing list