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

Reply via email to