[wxPython] Drawing multiple Items

Robin,

I've moved this over to the wxPython list, as it seemed a more
appropriate place for it.

To the folks, here, this thread started in a thread on the wx developers
list, about a wxCanvas widget (which will be a real boon for wxPython)

Robin Dunn wrote:

> Multiple objects can be created with a single call like:
>
> /* pseudocode*/ DrawRectangles(ListofCoordinates,ListofProperties).
>
> Note: this may sound sound pointless to C++ programmers (why not just
> write a loop?), but it can make a real performance difference for
> wxPython, and other scripting languages. It is also in keeping with the
> kind of high-level interface that we are going for.

You won't get as much benefit from this as you might think as the wrapper
code would have to first convert the Python list to a wxList before calling
the method.

HMMM. would it really take longer to build the wxList if there were a
large number of elements? I can see where for ten items, it might not
make sense, but what about for a thousand? Also, it wouldn't have to be
a wxList, is there some other data structure that would make more sense,
an array, whatever?

If something like this was really needed for the Python version
then it would be better to just "write a loop" in the wrapper code and call
the real method multiple times.

OK. I like that A LOT. In fact, I'd love to see it done for the DC's at
this point. (right now I have an application that has to draw 1000 dots
on the screen, each of them 4 pixels each. This means I have to loop
through 4000 tuples of coordinates, and use dc.DrawPoint on each one.
It's really pretty slow. I'd be happy if there were a DrawPoints,
DrawRectangles, etc that would use all the same brush and pen. A more
limited functionality, but still useful to me, and probably pretty easy
to impliment.

How hard would it be to add this? Would it have to be added by hand
every time a new version of the code got SWIGed, or could that be
automated?

One thing that is becoming clear to me is that there are real
limitations to working with a toolbox that was not designed with Python
in mind. Of course, writing a new GUI toolbox from scratch for Python
would be a huge effort that would be unlikely to happen, but it would be
nice. That's one of the nice things about TK. It was written for a
scripting language, and thus is somewhat more natural to use from one. I
know wxPython is not very "Pythonesque" because it is automatically
wrapped, and that that is the only practical way to keep up with wxWin
development. But I am wondering if it is time to start adding features
to wxPython that aren't in wxWin, to try to make it a little more
Pythonesque (like the above). How hard is it to add stuff to the
wrappers SWIG generates?

Anyway these are my thoughts. If we can get a good wxCanvas developed,
there will be no reason for anyone to use TK. (except for that pesky Mac
thing, but that may yet get solved)

···

--
Christopher Barker,
Ph.D.
cbarker@jps.net --- --- ---
http://www.jps.net/cbarker -----@@ -----@@ -----@@
                                   ------@@@ ------@@@ ------@@@
Water Resources Engineering ------ @ ------ @ ------ @
Coastal and Fluvial Hydrodynamics ------- --------- --------
------------------------------------------------------------------------
------------------------------------------------------------------------

>
> You won't get as much benefit from this as you might think as the

wrapper

> code would have to first convert the Python list to a wxList before

calling

> the method.

HMMM. would it really take longer to build the wxList if there were a
large number of elements? I can see where for ten items, it might not
make sense, but what about for a thousand? Also, it wouldn't have to be
a wxList, is there some other data structure that would make more sense,
an array, whatever?

I'm not saying that it won't be beneficial, just that there is (possibly
unexpected) overhead. You have to traverse the data an extra time, create a
duplicate of the data in memory, and if converting from a list of tuples to
a list of wxPoints or wxRects or something then there is an extra object
allocation/construction for each one too.

> If something like this was really needed for the Python version
> then it would be better to just "write a loop" in the wrapper code and

call

> the real method multiple times.

OK. I like that A LOT. In fact, I'd love to see it done for the DC's at
this point. (right now I have an application that has to draw 1000 dots
on the screen, each of them 4 pixels each. This means I have to loop
through 4000 tuples of coordinates, and use dc.DrawPoint on each one.
It's really pretty slow. I'd be happy if there were a DrawPoints,
DrawRectangles, etc that would use all the same brush and pen. A more
limited functionality, but still useful to me, and probably pretty easy
to impliment.

You can gain a little by using map() to traverse your list of tuples and
call dc.DrawPoint for you. DrawPoints would certainly be better though.

How hard would it be to add this? Would it have to be added by hand
every time a new version of the code got SWIGed, or could that be
automated?

Automated. I do it a lot already, look in the *.i sources for the
"%addmethods" SWIG directive. I use it whenever I need to wrap a particular
method differently than SWIG would normally do it, or when I want to add new
methods to a class. For example, yesterday we were talking about the
wxTreeItemData and related methods in wxTreeCtrl. Here is how they are
implemented for wxPython (in controls2.i), the first two are replacements
for existing C++ methods (in fact they call the C++ versions) and the second
two are additions:

    %addmethods {
        // [Get|Set]ItemData substitutes. Automatically create
wxPyTreeItemData
        // if needed.
        wxPyTreeItemData* GetItemData(const wxTreeItemId& item) {
            wxPyTreeItemData* data =
(wxPyTreeItemData*)self->GetItemData(item);
            if (data == NULL) {
                data = new wxPyTreeItemData();
                data->SetId(item); // set the id
                self->SetItemData(item, data);
            }
            return data;
        }

        void SetItemData(const wxTreeItemId& item, wxPyTreeItemData* data) {
            data->SetId(item); // set the id
            self->SetItemData(item, data);
        }

        // [Get|Set]PyData are short-cuts. Also made somewhat crash-proof
by
        // automatically creating data classes.
        PyObject* GetPyData(const wxTreeItemId& item) {
            wxPyTreeItemData* data =
(wxPyTreeItemData*)self->GetItemData(item);
            if (data == NULL) {
                data = new wxPyTreeItemData();
                data->SetId(item); // set the id
                self->SetItemData(item, data);
            }
            return data->GetData();
        }

        void SetPyData(const wxTreeItemId& item, PyObject* obj) {
            wxPyTreeItemData* data =
(wxPyTreeItemData*)self->GetItemData(item);
            if (data == NULL) {
                data = new wxPyTreeItemData(obj);
                data->SetId(item); // set the id
                self->SetItemData(item, data);
            } else
                data->SetData(obj);
        }
    }

One thing that is becoming clear to me is that there are real
limitations to working with a toolbox that was not designed with Python
in mind. Of course, writing a new GUI toolbox from scratch for Python
would be a huge effort that would be unlikely to happen, but it would be
nice. That's one of the nice things about TK. It was written for a
scripting language, and thus is somewhat more natural to use from one. I
know wxPython is not very "Pythonesque" because it is automatically
wrapped, and that that is the only practical way to keep up with wxWin
development. But I am wondering if it is time to start adding features
to wxPython that aren't in wxWin, to try to make it a little more
Pythonesque (like the above). How hard is it to add stuff to the
wrappers SWIG generates?

Not hard, and I welcome patches. <wink> The one problem right now is
documenting new methods. If there isn't an equivallent or related method in
C++ there's no place to put a PythonNote. However, once David's
documentation project gets a little further along we'll have a place for
things like this (and we should be able to toss out the C++ docs entirely)
so it is just a temporary problem.

Anyway these are my thoughts. If we can get a good wxCanvas developed,
there will be no reason for anyone to use TK. (except for that pesky Mac
thing, but that may yet get solved)

Agreed.

To any other Tkinter converts out there, this is the time to chime in let us
know the things about the Tk canvas you liked or what could be better.
Chris is compiling a list of desired features for the wxCanvas.

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com
http://wxpython.org Java give you jitters?
http://wxpros.com Relax with wxPython!

Anyway these are my thoughts. If we can get a good wxCanvas developed,
there will be no reason for anyone to use TK. (except for that pesky Mac
thing, but that may yet get solved)

Agreed.

To any other Tkinter converts out there, this is the time to chime in let us
know the things about the Tk canvas you liked or what could be better.
Chris is compiling a list of desired features for the wxCanvas.

I'm not a Tkinter convert but one thing that would make a new wxCanvas
useful for me is to be able to display PIL images. Currently my program has
both a PIL image and wxImage. All processing is done using PIL image but to
display it needs to be converted to wxImage and then converted to a bitmap
and displayed using dc.DrawBitmap.

Bob

···

-------------------------------------------------
Robert B. Klimek
NASA Glenn Research Center
robert.klimek@grc.nasa.gov
(216) 433-2837
--------------------------------------------------

Uh oh, Pandora's box has been opened. :slight_smile:

Here's a partial wishlist that I have. I *do* realize that a lot of these things require a very different way of thinking about drawing than wxWin currently supports.

    (1) Already mentioned: DrawXXXs() in order to avoid function call overhead when drawing a lot of stuff. These should allow python lists as arguments, but there should be some way to pass in whatever data structure is needed in the final form (e.g. a wxList). That way an experienced user can construct things properly in advance and skip all the overhead of type conversion. (This trick results in HUGE speedups in Tkinter code.)

    (2) User-assigned named (preferable) or numbered tags associated with every object placed on the canvas. Objects *can* have more than one tag. Again, these do not have to specified if the user doesn't care.

    (3) Ways to manipulate objects using those tags. It was fantastic to be able to select everything with a given tag (or set of tags) and then change, for example, the foreground color or line thickness.

    (4) Number (3) would require that objects on the canvas keep track of their own drawing parameters (line width, line style, background, etc.), but that's a good thing!

    (5) As long as objects are keeping track of their own drawing parameters, I should be able to pass those in when I draw them (rather than having to construct a brush).

    (6) Support for transformations (translate, scale, etc.) of objects or groups of objects. Even ones which have already been drawn.

    (7) Support for some kind of (text-based) metafile format. SVG seems pretty good for this, see below.

    (8) Interactivity support like: GetTopObjectUnderCursor() GetAllObjectsUnderCursor().

I'll stop now, before I sound *too* needy. :slight_smile:

I know that the idea of using SVG as a metafile was kicked around on that tread on wx-devel about canvases (before the thing got hijacked and diverted into irrelevant land). I personally really like SVG: it seems pretty clean and well thought out. There's a ton of extra crap in there that would not be required for a canvas, but being able to read (a subset) and write it would be great. Aside from the tag stuff (which might require a bit more thought) and anything to do with interactivity, most everything I've asked for could be done trivially in SVG.

-greg

···

At 04:53 PM 8/29/2000, Robin Dunn wrote:

To any other Tkinter converts out there, this is the time to chime in let us
know the things about the Tk canvas you liked or what could be better.
Chris is compiling a list of desired features for the wxCanvas.

----
greg Landrum (greglandrum@earthlink.net)
Software Carpenter/Computational Chemist

"Robert B. Klimek" wrote:

I'm not a Tkinter convert but one thing that would make a new wxCanvas
useful for me is to be able to display PIL images. Currently my program has
both a PIL image and wxImage. All processing is done using PIL image but to
display it needs to be converted to wxImage and then converted to a bitmap
and displayed using dc.DrawBitmap.

Well, remember that this is a wxCanvas, not a wxPython Canvas. I am
hopeing that it will be designed and built with Python in mind, but it
won't be totally Python-centric. I have no idea how it finally will be
implimented, but it looks for the moment like it will be able to deal
directly with wxImages, so at least you will have one less step. What
does it take to convert a PIL image to a wxImage? Perhaps this is
something that could be included in wxPython (or even built into the
wxCanvas!).

This brings up a problem with using a wrapper around a C++ toolbox,
rather than one designed for Python. Earlier Robin mentioned the issue
of converting a Python list to a wxList. This is similar to your problem
of converting a PIL image to a wxImage. I would love to see python data
types better integrated into wxWindows, but I'm not sure how the
wxWindows developers will feel about that. Mostly thought, what we need
are people willing to write the code. I'm afraid that a large portion of
wxPython users are like me: hopeless when it comes to C++. As the
wxPython user community grows to the same size as the wxWindows
community, perhaps the focus will shift a little. So far, the wxWindows
developers have been very responsive to wxPython issues, I think they
know that the fact that wxWindows can be used with Python really
increases its usefullness, and thus supporting Python is good for
wxWindows.

Keep sending your suggestions as to what you want in a wxCanvas. I'll be
compiling a list soon

-Chris

···

--
Christopher Barker,
Ph.D.
cbarker@jps.net --- --- ---
http://www.jps.net/cbarker -----@@ -----@@ -----@@
                                   ------@@@ ------@@@ ------@@@
Water Resources Engineering ------ @ ------ @ ------ @
Coastal and Fluvial Hydrodynamics ------- --------- --------
------------------------------------------------------------------------
------------------------------------------------------------------------