Re: tkinter and widget placement after resizing

2009-05-08 Thread John Posner

jamieson wrote:

i.e. start out with a window like this:

[1][4][7]
[2][5][8]
[3][6][9]


make the main window larger and end up with this:

[1][6]
[2][7]
[3][8]
[4][9]
[5


Here's a solution, using Label widgets for clarity. The keys are:

* start numbering from zero, not one
* use divmod() on an item's index within the list to determine the 
item's column/row position

* bind the Configure event for window resizing

# redo_layout.py

import sys
from Tkinter import *

CHAR_WIDTH = 10
PAD = 3
INIT_COL_COUNT = 3

def grid_positions(count, numcols):
   
   return a generator for (colnum, rownum) position tuples,
   given the total number of items and the number of columns

   the first column is filled with items, then the second, etc.
   
   numrows, rem = divmod(count, numcols)
   # need an extra row if there was a remainder
   if rem:
   numrows += 1

   # return value is a generator
   return ( divmod(i, numrows) for i in range(count) )

def place_labels(event):
   
   reposition all the items in the sequence label_list
   
   # assumption: all labels have same width
   label_width = label_list[0].winfo_width()
   window_width = frm.winfo_width()

   # calculate new column count
   new_col_count = window_width // (label_width+PAD)

   # get new position iterator
   pos_iter = grid_positions(LABEL_COUNT, new_col_count)

   # redo layout
   for lab in label_list:
   lab.grid_forget()
   colnum, rownum = pos_iter.next()
   lab.grid(column=colnum, row=rownum, padx=PAD, pady=PAD)

def create_labels(count):
   
   create a list of Label items,
   with text 1, 2, etc.
   
   return [ Label(frm, bg='cyan', width=CHAR_WIDTH, text=%d % i)
for i in range(count) ]

if __name__ == __main__:
   try:
   LABEL_COUNT = int(sys.argv[1])
   except (ValueError, IndexError):
   print ERROR: Must specify number of labels
   sys.exit(1)

   # Tkinter window and whole-window Frame
   root = Tk()
   frm = Frame(root)
   frm.pack(expand=True, fill=BOTH)

   # create some labels
   label_list = create_labels(LABEL_COUNT)

   # perform initial layout
   pos_iter = grid_positions(LABEL_COUNT, INIT_COL_COUNT)
   for lab in label_list:
   coloff, rowoff = pos_iter.next()
   lab.grid(column=coloff, row=rowoff, padx=PAD, pady=PAD)
   del pos_iter

   # event configuration: redo the layout when the window size changes
   frm.bind('Configure', place_labels)

   # go
   root.mainloop()

--
http://mail.python.org/mailman/listinfo/python-list


tkinter and widget placement after resizing

2009-05-07 Thread jamieson
Hello,

I've got a fairly simple GUI that places pmw.EntryFields into a window
starting in the upper left corner.  When the first column is filled
with these widgets I'd like to start a new column and continue
placement, and so on.  It is working now with the grid manager if I
explicitly set the max number of widgets per column, but if I resize
the main window there is wasted space as the number of widgets per
column is fixed.  I'd like to find a design that could change the
number of widgets per column when the window is resized.  Any
suggestions?

i.e. start out with a window like this:

[1][4][7]
[2][5][8]
[3][6][9]


make the main window larger and end up with this:

[1][6]
[2][7]
[3][8]
[4][9]
[5]
--
http://mail.python.org/mailman/listinfo/python-list