title: Why is my Tkinter Scrollbar not scrolling my Canvas?
body: <p>I am making a cube timer, and I want to make a table where you can see all of your times, including its scramble, date and other information using the text widget. If you insert a couple of times, it works fine, but when you do more than 50, you can't see some of the times. So, i'm using a scrollbar on a Canvas. I'm trying to make the canvas scroll down when you use the Scrollbar, but it doesn't seem to work. Here's my code.</p>
  <pre><code>class TimeTable(tk.Canvas):
  &quot;&quot;&quot;Creates a time table using a tk.Canvas&quot;&quot;&quot;
  def __init__(self, times, *args, **kwargs):
      &quot;&quot;&quot;
      :param times: list[CubeUtils.Time]
      &quot;&quot;&quot;
  
      # Initialize super class and define attributes
      super().__init__(*args, **kwargs)
      self.TIME_ATTRS = [&quot;Time&quot;, &quot;Scramble&quot;, &quot;Date&quot;, &quot;DNF&quot;]
      self.ScrollbarY = None
      self.fullscreen = False
      self.times = times
      self.frame = self.nametowidget(self.winfo_parent())
      self.parent = self.frame.nametowidget(self.frame)
      self.config(height=len(self.times)*15)
      self.frame.config(height=len(self.times)*15)
  
      # Insert time attributes in entries
      for column, attr in enumerate(self.TIME_ATTRS):
          text = tk.Text(self, font=(&quot;Arial&quot;, 15, &quot;bold&quot;), width=50, height=1)
          text.insert(&quot;0.0&quot;, attr)
          text.config(state=tk.DISABLED)
          text.grid(row=0, column=column+1, sticky=tk.E)
  
      # Insert times
      for time_count, time in enumerate(self.times):
          time_info = [time_count+1, time.time, time.scramble, time.date, time.DNF]
          if time_info[0] &gt; 49 and self.ScrollbarY is None:
              self.add_scrollbar()
  
          time_info_font = (&quot;Arial&quot;, 15, &quot;bold&quot;)
          for column, info in enumerate(time_info):
              if isinstance(info, int) and not isinstance(info, bool):
                  text = tk.Text(self, font=time_info_font, width=2 if len(str(info)) &lt;= 2 else len(str(info)), height=1, fg=&quot;#ff5000&quot;)
  
              else:
                  text = tk.Text(self, font=time_info_font, width=50, height=1, fg=&quot;#ff5000&quot;)
  
              text.insert(&quot;0.0&quot;, str(info))
              text.grid(row=time_count + 1, column=column, sticky=tk.E)
              text.config(state=tk.DISABLED)
  
      # Bindings
      self.parent.bind(&quot;&lt;F11&gt;&quot;, lambda key: self.toggle_fullscreen())
      self.parent.bind(&quot;&lt;Escape&gt;&quot;, lambda key: self.exit_fullscreen())
      self.parent.bind_all(&quot;&lt;MouseWheel&gt;&quot;, self.on_mousewheel)
  </code></pre>
  <p>Scrolling</p>
  <pre><code>def on_mousewheel(self, event):
      &quot;&quot;&quot;Scrolls the canvas using the mouse wheel&quot;&quot;&quot;
      self.yview_scroll(int(-1 * (event.delta / 120)), &quot;units&quot;)
  
  def add_scrollbar(self):
      &quot;&quot;&quot;Adds a scrollbar to the frame&quot;&quot;&quot;
      self.config(scrollregion=self.bbox(&quot;all&quot;))
      self.ScrollbarY = tk.Scrollbar(self.frame)
      self.config(yscrollcommand=self.ScrollbarY.set)
      self.ScrollbarY.config(command=self.yview)
      self.ScrollbarY.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH)
  </code></pre>
  <p>Fullscreening</p>
  <pre><code>def toggle_fullscreen(self):
      &quot;&quot;&quot;Toggles fullscreen on and off&quot;&quot;&quot;
      self.fullscreen = not self.fullscreen
      self.parent.attributes(&quot;-fullscreen&quot;, self.fullscreen)
  
  def exit_fullscreen(self):
      &quot;&quot;&quot;Exists fullscreen&quot;&quot;&quot;
      self.fullscreen = False
      self.parent.attributes(&quot;-fullscreen&quot;, self.fullscreen)
  </code></pre>
  <p>By the way, the times argument must be a list with elements of type Time, here is the code for that class.</p>
  <pre><code>class Time:
  &quot;&quot;&quot;Creates a time object that stores its time, scramble, date and whether or not it is a DNF&quot;&quot;&quot;
  def __init__(self, time, scramble, date, DNF=False):
      &quot;&quot;&quot;
      :param time: float
      :param scramble: str
      :param date: datetime.datetime
      :param DNF: bool
      &quot;&quot;&quot;
      if not isinstance(date, datetime.datetime):
          raise TypeError(&quot;date parameter must be of type datetime.datetime&quot;)
  
      if not isinstance(time, float):
          raise TypeError(&quot;time parameter must be of type float&quot;)
  
      if not isinstance(scramble, str):
          raise TypeError(&quot;scramble parameter must be of type str&quot;)
  
      if not isinstance(DNF, bool):
          raise TypeError(&quot;DNF parameter must be of type bool&quot;)
  
      self.time = time
      self.scramble = scramble
      self.date = datetime.datetime.strftime(date, &quot;%Y-%m-%d-%I:%M %p&quot;)
      self.DNF = DNF
  </code></pre>
  <p>I have tried reading web pages on effbot.com and other websites about putting a scrollbar on a canvas, but none of them are working for me.</p>
  <p>Edit: Thanks to acw1668 I have finished my TimeTable class, here is the finished code for that</p>
  <pre><code>class TimeTable(tk.Frame):
      &quot;&quot;&quot;Creates a time table using a tk.Canvas&quot;&quot;&quot;
      def __init__(self, parent, times, *args, **kwargs):
          &quot;&quot;&quot;
          :param parent: tk.Tk()
          :param times: list[CubeUtils.Time]
          &quot;&quot;&quot;
  
          # Initialize super class and define attributes
          super().__init__(*args, **kwargs)
          self.TIME_ATTRS = [&quot;Time&quot;, &quot;Scramble&quot;, &quot;Date&quot;, &quot;DNF&quot;]
          self.fullscreen = False
          self.times = times
          self.canvas = tk.Canvas(self)
          self.frame = tk.Frame(self.canvas)
          self.parent = parent
  
          self.canvas.pack(fill=tk.BOTH, expand=True)
          self.canvas.create_window(2, 2, window=self.frame, anchor=&quot;nw&quot;)
          self.frame.bind(&quot;&lt;Configure&gt;&quot;, self.on_config)
          self.parent.bind(&quot;&lt;MouseWheel&gt;&quot;, self.on_mousewheel)
          self.parent.bind(&quot;&lt;F11&gt;&quot;, lambda event: self.toggle_fullscreen())
          self.parent.bind(&quot;&lt;Escape&gt;&quot;, lambda event: self.exit_fullscreen())
          self.populate()
  
      def populate(self):
          &quot;&quot;&quot;Populates the frame with the times&quot;&quot;&quot;
          # Insert time attributes in text widgets
          for column, attr in enumerate(self.TIME_ATTRS):
              text = tk.Text(self.frame, font=(&quot;Arial&quot;, 15, &quot;bold&quot;), width=50, height=1)
              text.insert(&quot;0.0&quot;, attr)
              text.config(state=tk.DISABLED)
              column += 4
              text.grid(row=0, column=column)
  
          # Insert times in text widgets
          for time_count, time in enumerate(self.times):
              time_info = [time_count + 1, time.time, time.scramble, time.date, time.DNF]
              time_info_font = (&quot;Arial&quot;, 15, &quot;bold&quot;)
              for column, info in enumerate(time_info):
                  if isinstance(info, int) and not isinstance(info, bool):
                      text = tk.Text(self.frame, font=time_info_font, width=2 if len(str(info)) &lt;= 2 else len(str(info)),
                                     height=1, fg=&quot;#ff5000&quot;)
  
                  else:
                      text = tk.Text(self.frame, font=time_info_font, width=50, height=1, fg=&quot;#ff5000&quot;)
  
                  text.insert(&quot;0.0&quot;, str(info))
                  row = time_count + 1
                  column += 3
  
                  text.grid(row=row, column=column, sticky=tk.E)
                  text.config(state=tk.DISABLED)
  
      def on_config(self, event):
          &quot;&quot;&quot;Reset the scroll region to encompass the inner frame&quot;&quot;&quot;
          self.canvas.configure(scrollregion=self.canvas.bbox(&quot;all&quot;))
  
      def on_mousewheel(self, event):
          &quot;&quot;&quot;Scrolls the canvas using the mouse wheel&quot;&quot;&quot;
          self.canvas.yview_scroll(int(-1 * (event.delta / 120)), &quot;units&quot;)
  
      def toggle_fullscreen(self):
          &quot;&quot;&quot;Toggles fullscreen on and off&quot;&quot;&quot;
          self.fullscreen = not self.fullscreen
          self.parent.attributes(&quot;-fullscreen&quot;, self.fullscreen)
  
      def exit_fullscreen(self):
          &quot;&quot;&quot;Exists fullscreen&quot;&quot;&quot;
          self.fullscreen = False
          self.parent.attributes(&quot;-fullscreen&quot;, self.fullscreen)
  </code></pre>