Stephen Langer wrote:
> Hi --
>
> I'm hoping that someone can tell me if this is a bug or if I'm doing  
> something wrong.
>
> I have two HPaned widgets whose separators I'd like to keep  
> synchronized.  Both Paneds are in the same VBox, so they have the same  
> width.
>
> As described at http://faq.pygtk.org/index.py?req=show&file=faq19.013.htp 
> , I connect to the 'notify' signal for each pane to find out when the  
> separator has been moved.  The callback function blocks the signal for  
> the other  pane, changes its position to match the first pane, and  
> then unblocks the signal.
>
> The problem is that the signal doesn't seem to be blocked sometimes,  
> so the program goes into an infinite loop.  There are easy workarounds  
> for this, but they're ugly and unsatisfying.  In particular, the  
> program loops when the panes are first shown if the contents of two  
> diagonally opposite subpanes are larger than the contents of the other  
> two.
>
> I've appended short program that illustrates the problem.  Just  
> starting the program will put it into an infinite loop.  If you  
> replace paneMoved by paneMoved_workaround, the problem goes away.
>
> Why doesn't blocking the signal work?  Am I doing something wrong?
>
> I've run this test on OS X with python 2.5, gtk 2.14.7, and pygtk  
> 2.12.1, and on Linux with python 2.4, gtk 2.8.20, and pygtk 2.8.6.
>
> Thanks,
>        Steve
>
>
>
> import gtk
>
> def setPos(pane, signal, pos):
>      "Set a Paned position without propagating signals"
>      pane.handler_block(signal)
>      pane.set_position(pos)
>      pane.handler_unblock(signal)
>
> def paneMoved(pane, gparamspec):
>      "Callback for synchronizing Paned position changes"
>      if gparamspec.name == 'position':
>          pos = pane.get_position()
>          if pane is topPane:
>              print "top"
>              setPos(botPane, botSignal, pos)
>          else:
>              print "bottom"
>              setPos(topPane, topSignal, pos)
>
> count = 0
> def paneMoved_workaround(pane, gparamspec):
>      "Callback for synchronizing Paned position changes"
>      global count
>      if gparamspec.name == 'position':
>          count += 1
>          pos = pane.get_position()
>          if count == 1:
>              if pane is topPane:
>                  print "top"
>                  setPos(botPane, botSignal, pos)
>              else:
>                  print "bottom"
>                  setPos(topPane, topSignal, pos)
>          elif count > 1:
>              count = 0
>
> window = gtk.Window()
> box = gtk.VBox()
> window.add(box)
> window.connect("delete-event", gtk.main_quit)
>
> # Create two panes, one on top of the other
> topPane = gtk.HPaned()
> box.pack_start(topPane, expand=1, fill=1)
> botPane = gtk.HPaned()
> box.pack_start(botPane, expand=1, fill=1)
>
> # Synchronize the pane positions
> topSignal = topPane.connect('notify', paneMoved)
> botSignal = botPane.connect('notify', paneMoved)
>
> # If the displayed sizes of shortstring and longstring are different,
> # the program will enter an infinite loop after show_all().  If the
> # strings are identical, the program behaves correctly (no infinite
> # loop, the panes can be resized and stay synchronized).
> shortstring = "string"
> longstring = "long string"      # Try "String" too.
>
> # Put each string into two diagonally opposite labels in the panes.
> topPane.pack1(gtk.Label(longstring), resize=1, shrink=0)
> topPane.pack2(gtk.Label(shortstring), resize=1, shrink=0)
>
> botPane.pack1(gtk.Label(shortstring), resize=1, shrink=0)
> botPane.pack2(gtk.Label(longstring), resize=1, shrink=0)
>
> window.show_all()
>
> gtk.main()
>
>   
You have to allow the widgets to shrink - remove the "shrink=0" args 
from the pack1() and pack2() calls.

John
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to