By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,730 Members | 1,480 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,730 IT Pros & Developers. It's quick & easy.

Any idea why Tkinter scrollbar scrolls but contents on canvas didn't move together?

P: 17
Dear experts:

I am trying to add one xy-scrollbar on the canvas, then put lots of check buttons on the canvas. I got at least following 2 problems:

1.I can see the y-scroll bar but contents on canvas didn't move together when scroll y-scrollbar.
2.The x-scrollbar didn't show up as expected.

Do you have any idea? Thank you very much in advance!

Best regards,
Haiyan

Following is my code and you can run it directly to show the 2 problems above:
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2. from tkMessageBox import *
  3.  
  4. class BoatManager( Frame ):
  5.  
  6.    def __init__( self, name, cols, rows ):
  7.  
  8.       Frame.__init__( self )
  9.       self.name = name
  10.       self.cols = cols
  11.       self.rows = rows
  12.       self.master.title( "Apprentice" )
  13.  
  14.       # main frame fills entire container, expands if necessary
  15.       self.master.rowconfigure( 0, weight = 1 )
  16.       self.master.columnconfigure( 0, weight = 1 )
  17.       self.grid( sticky = W+E+N+S )
  18.  
  19.       # Scroll bar
  20.       xscrollbar = Scrollbar(self, orient=HORIZONTAL)
  21.       xscrollbar.grid(row=1, column=0, sticky=E+W)
  22.  
  23.       yscrollbar = Scrollbar(self)
  24.       yscrollbar.grid(row=0, column=1, sticky=N+S)
  25.  
  26.       # create Canvas component
  27.       self.canvas = Canvas(self, bd=0, scrollregion=(0, 0, 1000, 5000),
  28.                       yscrollcommand=yscrollbar.set,
  29.                       xscrollcommand=xscrollbar.set)
  30.       self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
  31.  
  32.       xscrollbar.config(command=self.canvas.xview)
  33.       yscrollbar.config(command=self.canvas.yview)
  34.  
  35.       # make the canvas expandable
  36.       self.canvas.grid_rowconfigure(0, weight=1)
  37.       self.canvas.grid_columnconfigure(0, weight=1)
  38.  
  39.       # Label for name
  40.       self.Label1 = Label( self.canvas, width = 40, height = 2, text = self.name, font = "Arial 20" )
  41.       self.Label1.grid( row = 0, rowspan = 1, column = 1, columnspan =self.cols+1, sticky = W+E+N+S )
  42.  
  43.       # Create one button object and one variable for all the buttons
  44.       self.Button_Name = [[Checkbutton() for i in range(self.rows)] for j in range(self.cols)]
  45.       self.buttonChecked = [[BooleanVar() for i in range(self.rows)] for j in range(self.cols)]
  46.       self.buttonNameVar = [[StringVar() for i in range(self.rows)] for j in range(self.cols)]
  47.  
  48.       for boat_num in xrange(self.cols):
  49.          for boat_slot in xrange(self.rows):
  50.  
  51.             # Freeze the column number to toggle whole column on or off
  52.             def handler_col(i=boat_num):
  53.                return self.select_full_column(i)
  54.  
  55.             # Freeze the row number to toggle whole row on or off
  56.             def handler_row(i=boat_slot):
  57.                return self.select_full_row(i)
  58.  
  59.             # For button Button_Name[0][0] to control all boats/slots
  60.             if boat_slot == 0 and boat_num == 0:
  61.                self.Button_Name[boat_num][boat_slot] = Checkbutton(self.canvas,
  62.                                                                   text = 'All Boats_Slots',
  63.                                                                   padx=5, pady=5,
  64.                                                                   relief = SUNKEN,
  65.                                                                   width = 15,
  66.                                                                   bg = 'Moccasin',
  67.                                                                   variable = self.buttonChecked[boat_num][boat_slot],
  68.                                                                   command = self.select_all_boats)
  69.  
  70.             # For button Button_Name[i][0], i is range(1,boat_num+1) to control all slots in boat i
  71.             elif boat_slot == 0:
  72.                self.Button_Name[boat_num][boat_slot] = Checkbutton(self.canvas,
  73.                                                                   text = 'Boat_' + str(boat_num),
  74.                                                                   padx=5, pady=5,
  75.                                                                   relief = SUNKEN,
  76.                                                                   width = 15,
  77.                                                                   bg = 'light yellow',
  78.                                                                   variable = self.buttonChecked[boat_num][boat_slot],
  79.                                                                   command = handler_col)
  80.  
  81.             # For button Button_Name[0][i], i is range(1,boat_slot+1) to control all slots in row i
  82.             elif boat_num == 0:
  83.                self.Button_Name[boat_num][boat_slot] = Checkbutton(self.canvas,
  84.                                                                   text = 'Slot_' + str(boat_slot),
  85.                                                                   padx=5, pady=5,
  86.                                                                   relief = SUNKEN,
  87.                                                                   width = 15,
  88.                                                                   bg = 'light yellow',
  89.                                                                   variable = self.buttonChecked[boat_num][boat_slot],
  90.                                                                   command = handler_row)
  91.  
  92.             # For single button control
  93.             else:
  94.                self.Button_Name[boat_num][boat_slot] = Checkbutton(self.canvas,
  95.                                                                   textvariable = self.buttonNameVar[boat_num][boat_slot],
  96.                                                                   padx=5, pady=5,
  97.                                                                   relief = SUNKEN,
  98.                                                                   variable = self.buttonChecked[boat_num][boat_slot],
  99.                                                                   width = 15,
  100.                                                                   command = self.select_current_slot)
  101.  
  102.             # Lay out check buttons with grid manager
  103.             self.Button_Name[boat_num][boat_slot].grid(row = boat_slot+1, rowspan = 1, column = boat_num + 2, columnspan = 1)
  104.  
  105.    # Full boats/slots toggle function
  106.    def select_all_boats(self):
  107.       for boat_num in xrange(self.cols):
  108.          for boat_slot in xrange(self.rows):
  109.             if boat_slot != 0 and boat_num != 0:
  110.                self.Button_Name[boat_num][boat_slot].toggle()
  111.  
  112.    # The column toggle function
  113.    def select_full_column(self, i):
  114.       for j in xrange(1, self.rows):
  115.          self.Button_Name[i][j].toggle()
  116.  
  117.    # The row toggle function
  118.    def select_full_row(self, i):
  119.       for j in xrange(1, self.cols):
  120.          self.Button_Name[j][i].toggle()
  121.  
  122.    def select_current_slot(self):
  123.       pass
  124.  
  125. boat1 = BoatManager('haiyan', 10,100)
  126. boat1.mainloop()
  127.  
Jul 31 '10 #1

✓ answered by bvdet

I think the value of each boat position in the table should be the dependent on the value of the controlling CheckBoxes instead of a toggle. It can be done like this:
Expand|Select|Wrap|Line Numbers
  1.     # Full boats/slots toggle function
  2.     def select_all_boats(self):
  3.         for boat_num in xrange(1, self.cols):
  4.             for boat_slot in xrange(1, self.rows):
  5.                 self.buttonChecked[boat_num][boat_slot].set(self.buttonChecked[0][0].get())
I have taken the liberty of incorporating this method into the following code:
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. '''
  4. Autohiding Scrollbars
  5. August 08, 1998 | Fredrik Lundh
  6. '''
  7. class AutoScrollbar(Scrollbar):
  8.     # a scrollbar that hides itself if it's not needed.  only
  9.     # works if you use the grid geometry manager.
  10.     def set(self, lo, hi):
  11.         if float(lo) <= 0.0 and float(hi) >= 1.0:
  12.             self.grid_remove()
  13.         else:
  14.             self.grid()
  15.         Scrollbar.set(self, lo, hi)
  16.     def pack(self, **kw):
  17.         raise TclError, "cannot use pack with this widget"
  18.     def place(self, **kw):
  19.         raise TclError, "cannot use place with this widget"
  20.  
  21. class BoatManager(object):
  22.  
  23.     def __init__( self, master, name, cols, rows ):
  24.         self.master = master
  25.         self.name = name
  26.         self.cols = cols
  27.         self.rows = rows
  28.         self.master.title( "Apprentice" )
  29.  
  30.         vscrollbar = AutoScrollbar(root)
  31.         vscrollbar.grid(row=0, column=1, sticky=N+S)
  32.         hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
  33.         hscrollbar.grid(row=1, column=0, sticky=E+W)
  34.  
  35.         canvas = Canvas(root,
  36.                         yscrollcommand=vscrollbar.set,
  37.                         xscrollcommand=hscrollbar.set)
  38.         canvas.grid(row=0, column=0, sticky=N+S+E+W)
  39.  
  40.         vscrollbar.config(command=canvas.yview)
  41.         hscrollbar.config(command=canvas.xview)
  42.  
  43.         # make the canvas expandable
  44.         root.grid_rowconfigure(0, weight=1)
  45.         root.grid_columnconfigure(0, weight=1)
  46.  
  47.         # create canvas contents
  48.  
  49.         frame = Frame(canvas)
  50.         frame.rowconfigure(1, weight=1)
  51.         frame.columnconfigure(1, weight=1)
  52.  
  53.         Label1 = Label( frame, width=40, height=2, text=self.name, font="Arial 20" )
  54.         Label1.grid( row=0, rowspan=1, column=1, columnspan=6, sticky=W+E+N+S )
  55.  
  56.         # Create one button object and one variable for each button
  57.         self.Button_Name = [[Checkbutton() for i in range(rows)] for j in range(cols)]
  58.         self.buttonChecked = [[BooleanVar() for i in range(rows)] for j in range(cols)]
  59.         self.buttonNameVar = [[StringVar() for i in range(rows)] for j in range(cols)]
  60.  
  61.         for boat_num in xrange(cols):
  62.             for boat_slot in xrange(rows):
  63.  
  64.                 # Freeze the column number to turn whole column on or off
  65.                 def handler_col(i=boat_num):
  66.                    return self.select_full_column(i)
  67.  
  68.                 # Freeze the row number to turn whole row on or off
  69.                 def handler_row(i=boat_slot):
  70.                    return self.select_full_row(i)
  71.  
  72.                 # For button Button_Name[0][0] to control all boats/slots
  73.                 if boat_slot == 0 and boat_num == 0:
  74.                     self.Button_Name[0][0] = Checkbutton(frame,
  75.                                                            text='All Boats_Slots',
  76.                                                            padx=5, pady=5,
  77.                                                            relief = SUNKEN,
  78.                                                            width = 15,
  79.                                                            bg = 'Moccasin',
  80.                                                            variable=self.buttonChecked[0][0],
  81.                                                            command=self.select_all_boats)
  82.  
  83.                 # For button Button_Name[i][0], i is range(1,boat_num+1) to control all slots in boat i
  84.                 elif boat_slot == 0:
  85.                     self.Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  86.                                                                    text='Boat_' + str(boat_num),
  87.                                                                    padx=5, pady=5,
  88.                                                                    relief = SUNKEN,
  89.                                                                    width = 15,
  90.                                                                    bg='light yellow',
  91.                                                                    variable = self.buttonChecked[boat_num][boat_slot],
  92.                                                                    command=handler_col)
  93.  
  94.                 # For button Button_Name[0][i], i is range(1,boat_slot+1) to control all slots in row i
  95.                 elif boat_num == 0:
  96.                     self.Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  97.                                                                    text='Slot_' + str(boat_slot),
  98.                                                                    padx=5, pady=5,
  99.                                                                    relief=SUNKEN,
  100.                                                                    width=15,
  101.                                                                    bg='light yellow',
  102.                                                                    variable=self.buttonChecked[boat_num][boat_slot],
  103.                                                                    command=handler_row)
  104.  
  105.                 # For single button control
  106.                 else:
  107.                     self.Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  108.                                                                    textvariable=buttonNameVar[boat_num][boat_slot],
  109.                                                                    padx=5, pady=5,
  110.                                                                    relief=SUNKEN,
  111.                                                                    variable=self.buttonChecked[boat_num][boat_slot],
  112.                                                                    width=15,
  113.                                                                    command=self.select_current_slot)
  114.  
  115.                 # Lay out check buttons with grid manager
  116.                 self.Button_Name[boat_num][boat_slot].grid(row = boat_slot+1, rowspan = 1, column = boat_num + 2, columnspan = 1)
  117.  
  118.         canvas.create_window(0, 0, anchor=NW, window=frame)
  119.         frame.update_idletasks()
  120.         canvas.config(scrollregion=canvas.bbox("all"))
  121.  
  122.     # Full boats/slots control function
  123.     def select_all_boats(self):
  124.         for boat_num in xrange(1, self.cols):
  125.             for boat_slot in xrange(1, self.rows):
  126.                 self.buttonChecked[boat_num][boat_slot].set(self.buttonChecked[0][0].get())
  127.  
  128.     # The column control function
  129.     def select_full_column(self, i):
  130.         for j in xrange(1, self.rows):
  131.             self.buttonChecked[i][j].set(self.buttonChecked[i][0].get())
  132.  
  133.     # The row control function
  134.     def select_full_row(self, i):
  135.         for j in xrange(1, self.cols):
  136.             self.buttonChecked[j][i].set(self.buttonChecked[0][i].get())
  137.  
  138.     def select_current_slot(self):
  139.       pass
  140.  
  141.  
  142. if __name__ == "__main__":
  143.  
  144.    rows = 100
  145.    cols = 10
  146.    root = Tk()
  147.    boat1 = BoatManager(root, 'haiyan', cols, rows)
  148.    root.mainloop()
We should give credit to Fredrik Lundh for the AutoScrollBar.

Share this Question
Share on Google+
7 Replies


P: 17
I modified the scroll bar and canvas part a little bit from self to self.master as follows, and now x-scroll bar showed up as well, but contents on the canvas still doesn't move when scroll the scrollbar.
Expand|Select|Wrap|Line Numbers
  1.       # Scroll bar
  2.       xscrollbar = Scrollbar(self.master, orient=HORIZONTAL)
  3.       xscrollbar.grid(row=1, column=0, sticky=E+W)
  4.  
  5.       yscrollbar = Scrollbar(self.master)
  6.       yscrollbar.grid(row=0, column=1, sticky=N+S)
  7.  
  8.       # create Canvas component
  9.       self.canvas = Canvas(self.master, bd=0, scrollregion=(0, 0, 1000, 5000),
  10.                       xscrollcommand=xscrollbar.set,
  11.                       yscrollcommand=yscrollbar.set)
  12.       self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
  13.  
Aug 1 '10 #2

bvdet
Expert Mod 2.5K+
P: 2,851
Haiyan,

I have never had much luck with scroll bars on canvases. I think you should add the table of CheckBoxes in a Frame and place the Frame on the canvas. The scrollbars also should be on the canvas. If I am able to make something work, I will post again. Please do the same.

Regards,
bvdet
Aug 2 '10 #3

P: 17
Hi, Bvdet:

Thanks a lot for your help! I modified the script based on your suggestion, and looks like get it working. But I don't like the following implementation, and I hope to keep my original class definition because I need to use the scroll bar lots of places.

Following is the working code but not in class definition:
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. class AutoScrollbar(Scrollbar):
  4.     # a scrollbar that hides itself if it's not needed.  only
  5.     # works if you use the grid geometry manager.
  6.     def set(self, lo, hi):
  7.         if float(lo) <= 0.0 and float(hi) >= 1.0:
  8.             # grid_remove is currently missing from Tkinter!
  9.             self.tk.call("grid", "remove", self)
  10.         else:
  11.             self.grid()
  12.         Scrollbar.set(self, lo, hi)
  13.     def pack(self, **kw):
  14.         raise TclError, "cannot use pack with this widget"
  15.     def place(self, **kw):
  16.         raise TclError, "cannot use place with this widget"
  17.  
  18. # create scrolled canvas
  19.  
  20. root = Tk()
  21.  
  22. vscrollbar = AutoScrollbar(root)
  23. vscrollbar.grid(row=0, column=1, sticky=N+S)
  24. hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
  25. hscrollbar.grid(row=1, column=0, sticky=E+W)
  26.  
  27. canvas = Canvas(root,
  28.                 yscrollcommand=vscrollbar.set,
  29.                 xscrollcommand=hscrollbar.set)
  30. canvas.grid(row=0, column=0, sticky=N+S+E+W)
  31.  
  32. vscrollbar.config(command=canvas.yview)
  33. hscrollbar.config(command=canvas.xview)
  34.  
  35. # make the canvas expandable
  36. root.grid_rowconfigure(0, weight=1)
  37. root.grid_columnconfigure(0, weight=1)
  38.  
  39. # create canvas contents
  40.  
  41. frame = Frame(canvas)
  42. frame.rowconfigure(1, weight=1)
  43. frame.columnconfigure(1, weight=1)
  44.  
  45. # Label for name
  46. Label1 = Label( frame, width = 40, height = 2, text = 'haiyan', font = "Arial 20" )
  47. Label1.grid( row = 0, rowspan = 1, column = 1, columnspan =6, sticky = W+E+N+S )
  48.  
  49. rows = 100
  50. cols = 10
  51. # Create one button object and one variable for all the buttons
  52. Button_Name = [[Checkbutton() for i in range(rows)] for j in range(cols)]
  53. buttonChecked = [[BooleanVar() for i in range(rows)] for j in range(cols)]
  54. buttonNameVar = [[StringVar() for i in range(rows)] for j in range(cols)]
  55.  
  56. for boat_num in xrange(cols):
  57.    for boat_slot in xrange(rows):
  58.  
  59.       # Freeze the column number to toggle whole column on or off
  60.       def handler_col(i=boat_num):
  61.          return select_full_column(i)
  62.  
  63.       # Freeze the row number to toggle whole row on or off
  64.       def handler_row(i=boat_slot):
  65.          return select_full_row(i)
  66.  
  67.       # For button Button_Name[0][0] to control all boats/slots
  68.       if boat_slot == 0 and boat_num == 0:
  69.          Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  70.                                                             text = 'All Boats_Slots',
  71.                                                             padx=5, pady=5,
  72.                                                             relief = SUNKEN,
  73.                                                             width = 15,
  74.                                                             bg = 'Moccasin',
  75.                                                             variable = buttonChecked[boat_num][boat_slot],)
  76. ##                                                            command = select_all_boats)
  77.  
  78.       # For button Button_Name[i][0], i is range(1,boat_num+1) to control all slots in boat i
  79.       elif boat_slot == 0:
  80.          Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  81.                                                             text = 'Boat_' + str(boat_num),
  82.                                                             padx=5, pady=5,
  83.                                                             relief = SUNKEN,
  84.                                                             width = 15,
  85.                                                             bg = 'light yellow',
  86.                                                             variable = buttonChecked[boat_num][boat_slot],)
  87. ##                                                            command = handler_col)
  88.  
  89.       # For button Button_Name[0][i], i is range(1,boat_slot+1) to control all slots in row i
  90.       elif boat_num == 0:
  91.          Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  92.                                                             text = 'Slot_' + str(boat_slot),
  93.                                                             padx=5, pady=5,
  94.                                                             relief = SUNKEN,
  95.                                                             width = 15,
  96.                                                             bg = 'light yellow',
  97.                                                             variable = buttonChecked[boat_num][boat_slot],)
  98. ##                                                            command = handler_row)
  99.  
  100.       # For single button control
  101.       else:
  102.          Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  103.                                                             textvariable = buttonNameVar[boat_num][boat_slot],
  104.                                                             padx=5, pady=5,
  105.                                                             relief = SUNKEN,
  106.                                                             variable = buttonChecked[boat_num][boat_slot],
  107.                                                             width = 15,)
  108. ##                                                            command = select_current_slot)
  109.  
  110.       # Lay out check buttons with grid manager
  111.       Button_Name[boat_num][boat_slot].grid(row = boat_slot+1, rowspan = 1, column = boat_num + 2, columnspan = 1)
  112.  
  113.  
  114. canvas.create_window(0, 0, anchor=NW, window=frame)
  115.  
  116. frame.update_idletasks()
  117.  
  118. canvas.config(scrollregion=canvas.bbox("all"))
  119.  
  120. root.mainloop()
  121.  
Thanks a lot!

Haiyan
Aug 2 '10 #4

bvdet
Expert Mod 2.5K+
P: 2,851
Thanks Haiyan for posting the solution. I learned something from this!
Aug 2 '10 #5

P: 17
Hi, Bvdet:

You are welcome! But I still have trouble to merge into my original class definition. You know the solution I post above is to create one canvas with scrollbar, then create one frame on the canvas, then put the table of checkbox into the frame.

When I am trying to merge into my original class definition. I didn't understand the relationship of self, self.master and canvas and didn't get it implemented correctly. Please excuse me I didn't read some documents about Python GUI yet, and it is my first time to write Python GUI.

Could you please give me some hint so I can put the scrollbar implementation in my original class? I hope to understand it because I need the scrollbar implementation of lots of places, some of them are not in the main GUI.

Thanks a lot!
Aug 2 '10 #6

bvdet
Expert Mod 2.5K+
P: 2,851
I think the value of each boat position in the table should be the dependent on the value of the controlling CheckBoxes instead of a toggle. It can be done like this:
Expand|Select|Wrap|Line Numbers
  1.     # Full boats/slots toggle function
  2.     def select_all_boats(self):
  3.         for boat_num in xrange(1, self.cols):
  4.             for boat_slot in xrange(1, self.rows):
  5.                 self.buttonChecked[boat_num][boat_slot].set(self.buttonChecked[0][0].get())
I have taken the liberty of incorporating this method into the following code:
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. '''
  4. Autohiding Scrollbars
  5. August 08, 1998 | Fredrik Lundh
  6. '''
  7. class AutoScrollbar(Scrollbar):
  8.     # a scrollbar that hides itself if it's not needed.  only
  9.     # works if you use the grid geometry manager.
  10.     def set(self, lo, hi):
  11.         if float(lo) <= 0.0 and float(hi) >= 1.0:
  12.             self.grid_remove()
  13.         else:
  14.             self.grid()
  15.         Scrollbar.set(self, lo, hi)
  16.     def pack(self, **kw):
  17.         raise TclError, "cannot use pack with this widget"
  18.     def place(self, **kw):
  19.         raise TclError, "cannot use place with this widget"
  20.  
  21. class BoatManager(object):
  22.  
  23.     def __init__( self, master, name, cols, rows ):
  24.         self.master = master
  25.         self.name = name
  26.         self.cols = cols
  27.         self.rows = rows
  28.         self.master.title( "Apprentice" )
  29.  
  30.         vscrollbar = AutoScrollbar(root)
  31.         vscrollbar.grid(row=0, column=1, sticky=N+S)
  32.         hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
  33.         hscrollbar.grid(row=1, column=0, sticky=E+W)
  34.  
  35.         canvas = Canvas(root,
  36.                         yscrollcommand=vscrollbar.set,
  37.                         xscrollcommand=hscrollbar.set)
  38.         canvas.grid(row=0, column=0, sticky=N+S+E+W)
  39.  
  40.         vscrollbar.config(command=canvas.yview)
  41.         hscrollbar.config(command=canvas.xview)
  42.  
  43.         # make the canvas expandable
  44.         root.grid_rowconfigure(0, weight=1)
  45.         root.grid_columnconfigure(0, weight=1)
  46.  
  47.         # create canvas contents
  48.  
  49.         frame = Frame(canvas)
  50.         frame.rowconfigure(1, weight=1)
  51.         frame.columnconfigure(1, weight=1)
  52.  
  53.         Label1 = Label( frame, width=40, height=2, text=self.name, font="Arial 20" )
  54.         Label1.grid( row=0, rowspan=1, column=1, columnspan=6, sticky=W+E+N+S )
  55.  
  56.         # Create one button object and one variable for each button
  57.         self.Button_Name = [[Checkbutton() for i in range(rows)] for j in range(cols)]
  58.         self.buttonChecked = [[BooleanVar() for i in range(rows)] for j in range(cols)]
  59.         self.buttonNameVar = [[StringVar() for i in range(rows)] for j in range(cols)]
  60.  
  61.         for boat_num in xrange(cols):
  62.             for boat_slot in xrange(rows):
  63.  
  64.                 # Freeze the column number to turn whole column on or off
  65.                 def handler_col(i=boat_num):
  66.                    return self.select_full_column(i)
  67.  
  68.                 # Freeze the row number to turn whole row on or off
  69.                 def handler_row(i=boat_slot):
  70.                    return self.select_full_row(i)
  71.  
  72.                 # For button Button_Name[0][0] to control all boats/slots
  73.                 if boat_slot == 0 and boat_num == 0:
  74.                     self.Button_Name[0][0] = Checkbutton(frame,
  75.                                                            text='All Boats_Slots',
  76.                                                            padx=5, pady=5,
  77.                                                            relief = SUNKEN,
  78.                                                            width = 15,
  79.                                                            bg = 'Moccasin',
  80.                                                            variable=self.buttonChecked[0][0],
  81.                                                            command=self.select_all_boats)
  82.  
  83.                 # For button Button_Name[i][0], i is range(1,boat_num+1) to control all slots in boat i
  84.                 elif boat_slot == 0:
  85.                     self.Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  86.                                                                    text='Boat_' + str(boat_num),
  87.                                                                    padx=5, pady=5,
  88.                                                                    relief = SUNKEN,
  89.                                                                    width = 15,
  90.                                                                    bg='light yellow',
  91.                                                                    variable = self.buttonChecked[boat_num][boat_slot],
  92.                                                                    command=handler_col)
  93.  
  94.                 # For button Button_Name[0][i], i is range(1,boat_slot+1) to control all slots in row i
  95.                 elif boat_num == 0:
  96.                     self.Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  97.                                                                    text='Slot_' + str(boat_slot),
  98.                                                                    padx=5, pady=5,
  99.                                                                    relief=SUNKEN,
  100.                                                                    width=15,
  101.                                                                    bg='light yellow',
  102.                                                                    variable=self.buttonChecked[boat_num][boat_slot],
  103.                                                                    command=handler_row)
  104.  
  105.                 # For single button control
  106.                 else:
  107.                     self.Button_Name[boat_num][boat_slot] = Checkbutton(frame,
  108.                                                                    textvariable=buttonNameVar[boat_num][boat_slot],
  109.                                                                    padx=5, pady=5,
  110.                                                                    relief=SUNKEN,
  111.                                                                    variable=self.buttonChecked[boat_num][boat_slot],
  112.                                                                    width=15,
  113.                                                                    command=self.select_current_slot)
  114.  
  115.                 # Lay out check buttons with grid manager
  116.                 self.Button_Name[boat_num][boat_slot].grid(row = boat_slot+1, rowspan = 1, column = boat_num + 2, columnspan = 1)
  117.  
  118.         canvas.create_window(0, 0, anchor=NW, window=frame)
  119.         frame.update_idletasks()
  120.         canvas.config(scrollregion=canvas.bbox("all"))
  121.  
  122.     # Full boats/slots control function
  123.     def select_all_boats(self):
  124.         for boat_num in xrange(1, self.cols):
  125.             for boat_slot in xrange(1, self.rows):
  126.                 self.buttonChecked[boat_num][boat_slot].set(self.buttonChecked[0][0].get())
  127.  
  128.     # The column control function
  129.     def select_full_column(self, i):
  130.         for j in xrange(1, self.rows):
  131.             self.buttonChecked[i][j].set(self.buttonChecked[i][0].get())
  132.  
  133.     # The row control function
  134.     def select_full_row(self, i):
  135.         for j in xrange(1, self.cols):
  136.             self.buttonChecked[j][i].set(self.buttonChecked[0][i].get())
  137.  
  138.     def select_current_slot(self):
  139.       pass
  140.  
  141.  
  142. if __name__ == "__main__":
  143.  
  144.    rows = 100
  145.    cols = 10
  146.    root = Tk()
  147.    boat1 = BoatManager(root, 'haiyan', cols, rows)
  148.    root.mainloop()
We should give credit to Fredrik Lundh for the AutoScrollBar.
Aug 2 '10 #7

P: 17
Hi, Bvdet:

Thanks a lot!

Yes, the credit should give to both Fredrik Lundh and you!

I also tried another piece of script and merged into the original class and it also works. The script is as follows:
Expand|Select|Wrap|Line Numbers
  1.       self.canv = Canvas ( self, width=1200, height=800,
  2.           scrollregion=(0, 0, 1200, 800) )
  3.       self.canv.grid ( row=0, column=0 )
  4.  
  5.       self.scrollY = Scrollbar ( self, orient=VERTICAL,
  6.           command=self.canv.yview )
  7.       self.scrollY.grid ( row=0, column=1, sticky=N+S )
  8.  
  9.       self.scrollX = Scrollbar ( self, orient=HORIZONTAL,
  10.           command=self.canv.xview )
  11.       self.scrollX.grid ( row=1, column=0, sticky=E+W )
  12.  
  13.       self.canv["xscrollcommand"]  =  self.scrollX.set
  14.       self.canv["yscrollcommand"]  =  self.scrollY.set
  15.  
  16.       self.frame = Frame(self.canv)
  17.       self.frame.rowconfigure(1, weight=1)
  18.       self.frame.columnconfigure(1, weight=1)
  19.  
Thanks again!

Haiyan
Aug 2 '10 #8

Post your reply

Sign in to post your reply or Sign up for a free account.