[PythonCAD] Next rev of PythonCAD class diagram, and more questions

Art Haas ahaas at airmail.net
Wed Oct 19 22:36:18 CEST 2005


On Wed, Oct 19, 2005 at 03:16:01PM -0400, Stuart Brorson wrote:
> Hi --
> 
> I have been continuing to study PythonCAD so that I can make more
> changes/improvements.  To this end I have added more stuff to my pseudo-UML
> class diagram.  Please find a .pdf copy of the diagram attached.  If anybody
> wants the original Dia file, let me know and I will post it.
> 
> Art -- Does the class diagram look correct to you?

I'll have to look at it later as I don't have a '.dia' viewer on my
primary machine. I think the other machine around here has something
that will display those files.

> 
> Now for a couple of questions:
> 
> *  I upgraded my installation of Python to 2.4.2 in order to get rid of
> an XML problem when reading files. Now, however, I get this error message
> when trying > to read in a PythonCAD file:
> 
> [sdb at Fermat pythoncad-sdb-20051016]$ gtkpycad.py Test.xml.gz
> Opening 'Test.xml.gz'
> [ ... snip ... ]
>   File "/usr/lib/python2.4/site-packages/PythonCAD/Generic/dimension.py", line
> 2201, in __eq__
>     for _key in Dimstyle.__defaults.keys():
> NameError: global name 'Dimstyle' is not defined
> 
> Any ideas about what's wrong?  I will look at this myself later, but
> perhaps one of the gurus here already knows about this.

A typo - 'Dimstyle' should be 'DimStyle'. Oops ...

[ ... goes to other window ... ]

Fixed and checked in.

> *  Art -- further to the point of highlighting selected objects:  What are
> your thoughts on using signals to tell objects to highlight?  I guess that
> if you could write a couple of sentences giving an example how signaling
> accomplishes actions in PythonCAD (for example, how signaling works when
> moving an object) then that would help me understand how this should work.
> I *did* read the documentation you pointed me to, BTW, but still need a
> little more insight into how it works in PythonCAD.  Thanks!

Let me give you a simpler example for the messaging system than moving,
partly because moving is somewhat complex and also I'm looking at that
code right now and it will probably be changing. Pretend that you want
to change the thickness of a segment in a drawing. You select the
segment, go to 'Modify' -> 'Change' -> 'Thickness', enter the new
thickness, then click the 'OK' button, and if things go according to
plan the selected segment(s) will all have the value you specified in
the dialog box for their thickness.

The code that sets the thickness on segments is in the
'graphicobject.py' file; look for the setThickness() method. A
simplified version is below:

	def setThickness(self, t):
		ot = self.__thickness
		if abs(ot - t) > 1e-10:
			self.__thickness = t
			self.sendMessage('thickness_changed', ot)
			self.modified()

The real method has some more error checking and bits around the
assignment to the 'self.__thickness' value, , but for example purpose
what is above will do. First, a simple test is done to determine
if the new thickness 't' is different from the original thickness 'ot'.
If so, the new thickness value is assigned, then the sendMessage()
call is made. The code for sendMessage() is in the 'message.py' file,
btw. The sendMessage() call first argument is a text string which
gives the type of message being sent, in this case 'thickness_changed'.
The second argument is the previous value of the thickness. After
the sendMessage() call completes, the modified() method is invoked, and
it sends out a 'modified' message - see the code in 'entity.py'.

That is all fine and good, but it does not accomplish anything unless
some other entities are listening for either 'thickness_changed' and
'modified' messages. In real drawings, the Segment entity will have
an associated SegmentLog entity which keeps track of the changes made
on the Segment instance. This SegmentLog entity will listen for
'thickness_changed' messages because SegmentLog is a subclass of
the GraphicObjectLog class (see the 'segment.py' file), and look
at the 'graphicobject.py' file for the GraphicObjectLog methods.
In the GraphicObjectLog::__init__() method, you'll see a couple
lines where a connect() method call is used, and in particular the
one regarding the thickness value is:

	obj.connect('thickness_changed', self._thicknessChanged)

The file where the connect() code is defined is 'message.py'. Now,
whenever the Segment instance invokes the sendMessage() call with
a 'thickness_changed', message, the _thicknessChanged() method
in the GraphicObjectLog class is executed. All that method does
is store off the old thickness value in the list of changes that
have been applied to the Segment.

The pairing of sendMessage('message') and connect('message') calls
is the guts of the messaging system. Using this approach for
inter-entity communication has worked out well, as it permits
the entities to indicate that they have been changed in some way
and that any interested party can use this information as is needed, but
the changed entity itself doesn't have to know anything about any
entities that are listening in via the connect() calls.

> *  Finally, any progress on the patches I sent in?  I'm just curious,
> not trying to be pushy!  Let me know if I can do anything to help!

The patch was applied, and then I've gone in and made further changes
to what you sent. For example, the patch to the 'gtkmenu.py' file adding
all the underscores for mnemonics is in essentially unchanged, as was
the patch to 'prompt.py'. Your patch for 'gtkimage.py' pointed out a
bug fix to connecting to the 'self.__entry' gtk.Entry widget, so
thanks for spotting and fixing that. You'd wondered why the connect()
call to the window_general_event() function was commented out, and
after looking at the code I realized that I was just using it for
debug purposes, but your earlier mail where you point out that hitting
the 'Esc' key was not doing what you expect made me activate the
window_general_event() function and have it handle the 'Esc' key, neatly
solving the problem. Also, the '.dia', '.pdf', and '.sxw' files
are added into the repo.

I've been making lots of changes in the code over the last day or two,
and while there are still glitches here and there, brave souls can
do an 'svn update' and pull the latest changes. Nearly all the changes
I've been making deal with handling the recent Quadtree changes allowing
multiple entities to be stored with equivalent values. In particular,
this change affected the Quadtree find() method, and that call is
used in lots of places in the code. In another day or two I'll be
more confident that the code has been adjusted correctly to handle
the Quadtree change, but for now those wanting to update their repos can
do so but expect a few snags here and there. The 'Dimstyle' fix
mentioned above is on the repo, too.

Art
-- 
Man once surrendering his reason, has no remaining guard against absurdities
the most monstrous, and like a ship without rudder, is the sport of every wind.

-Thomas Jefferson to James Smith, 1822


More information about the PythonCAD mailing list