[pygtk] synchronizing HPaned widgets
Stephen Langer
stephen.langer at nist.gov
Fri Feb 6 03:19:12 WST 2009
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()
--
-- EMail: stephen.langer at nist.gov Phone: (301)
975-5423 --
-- WWW: http://math.nist.gov/mcsd/Staff/SLanger/ Fax: (301)
975-3553 --
-- Mail: NIST; 100 Bureau Drive -- Stop 8910; Gaithersburg, Md
20899-8910 --
-- "I don't think this will work. That's why it's
science." --
-- Naomi Langer (age 6), 17 Feb
2003 --
More information about the pygtk
mailing list