PAM Frequently Asked Questions

This page contains answers to frequently asked Pam questions.


Index to FAQ

Complete Screen Redraw

Question: pam.update() does not always seem to do a complete redraw of the window. Is there a call similar to pam.update() that will cause a complete redraw of a window?

Answer: Calling pam.event_loop() will guarantee that all events (including (un)mapping of windows) get handled properly. If pam.event_loop() does not work, you've got a "dead" window that won't respond to events and will therefore not get redrawn.

The most frequent reason that pam.update() fails to work is that the programmer forgets to place a pam.update() directly after the command that adds the window to the screen. Due to an Amulet quirk, Pam must map a window before it draws anything in the window. If the programmer does not call pam.update() until after several objects have been added to the window, then pam.update() maps the window but does not draw the objects. Calling pam.update() a second time will not work. The only solution in this case is to call pam.event_loop().

Absolute vs Relative Addressing in PAM

Question: I have a group that contains a rectangle. When I move the group, the rectangle should move with it but instead it behaves erratically. The code I use is shown below. What's wrong?
class Red_square( pam.Rectangle ):
   fill_style = pam.Am_Red

class Board( pam.Group ):
   components = [
      (  'back' ,
            lambda: Red_square (
               left   = pam.Formula( 'self.owner.left'   ),
               top    = pam.Formula( 'self.owner.top'    ),
               width  = pam.Formula( 'self.owner.width'  ),
               height = pam.Formula( 'self.owner.height' )
         ))
     ]

win = pam.Window( width = 400, height = 400 )
pam.screen.add_part( win )
board = Board( top = 0, left = 0, height = 100, width = 100 )
win.add_part( board )
mgi = pam.Move_Grow_Interactor()
mgi.growing = 0
win.add_part( mgi )
pam.event_loop()
Answer: Pam uses relative coordinates for objects within a group but the formulas in the Red_square code are using absolute coordinates. The left and top of the rectangle should be set to 0, rather than to the left and top of the group.

Implementing Quit Buttons

Question: When I invoke sys.exit or pam.exit from a quit button, my application crashes. How can I fix this problem?

Answer: The solution is a two-step solution and is similar to what you would do in Amulet:

Step 1:
In the code that creates your graphical application, put either a sys.exit or pam.exit call immediately after your call to pam.event_loop. Use sys.exit if you want to quit Python. Use pam.exit if you want to shut down pam and Amulet but return to the interpreter prompt (you will no longer be able to use pam however--if you still want to use pam, you should instead simply destroy the windows your graphical application used by invoking the destroy method on each of the windows).

Step 2:
Have your quit button call pam.exit_event_loop. This call causes pam to exit the event loop and return control to the Python interpreter. In particular, control gets returned to the point in your program that is immediately after your call to pam.event_loop(). Your sys.exit, pam.exit, or destroy window commands will kick in, causing the correct action to occur.