title: Add scrollbar to updating label in tkinter python?
body: <p>The issue I have is that I can't find a way to incorporate a scrollbar with my current code. I have an updating label that adds text that is being spat out by a subprocess but the data disappears as more data is created. In this case, the numbers disappear out of sight. Here is my current code:</p>
  <pre><code>import logging
  import os
  import sys
  from subprocess import Popen, PIPE, STDOUT
  from threading import Thread
  
  try:
      import tkinter as tk
  except ImportError: # Python 3
      import tkinter as tk
  
  info = logging.getLogger(__name__).info
  
  # define dummy subprocess to generate some output
  cmd = [sys.executable or &quot;python&quot;, &quot;-u&quot;, &quot;-c&quot;, &quot;&quot;&quot;
  import itertools, time
  
  for i in itertools.count():
      print(i)
      time.sleep(0.5)
  &quot;&quot;&quot;]
  
  class ShowProcessOutputDemo:
      def __init__(self, root):
          &quot;&quot;&quot;Start subprocess, make GUI widgets.&quot;&quot;&quot;
          self.root = root
  
          # start subprocess
          self.proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
  
          # stop subprocess using a button
          tk.Button(root, text=&quot;Stop subprocess&quot;, command=self.stop).pack()
  
          self.label = tk.Label(root) # put subprocess output here
          self.label.pack()
  
          # Create a buffer for the stdout
          self.stdout_data = &quot;&quot;
          # Create a new thread that will read stdout and write the data to
          # `self.stdout_buffer`
          thread = Thread(target=self.read_output, args=(self.proc.stdout, ))
          thread.start()
  
          # A tkinter loop that will show `self.stdout_data` on the screen
          self.show_stdout()
  
      def read_output(self, pipe):
          &quot;&quot;&quot;Read subprocess' output and store it in `self.stdout_data`.&quot;&quot;&quot;
          while True:
              data = os.read(pipe.fileno(), 1 &lt;&lt; 20)
              # Windows uses: &quot;\r\n&quot; instead of &quot;\n&quot; for new lines.
              data = data.replace(b&quot;\r\n&quot;, b&quot;\n&quot;)
              if data:
                  info(&quot;got: %r&quot;, data)
                  self.stdout_data += data.decode()
              else:  # clean up
                  info(&quot;eof&quot;)
                  self.root.after(5000, self.stop) # stop in 5 seconds
                  return None
  
      def show_stdout(self):
          &quot;&quot;&quot;Read `self.stdout_data` and put the data in the GUI.&quot;&quot;&quot;
          self.label.config(text=self.stdout_data.strip(&quot;\n&quot;))
          self.root.after(100, self.show_stdout)
  
      def stop(self, stopping=[]):
          &quot;&quot;&quot;Stop subprocess and quit GUI.&quot;&quot;&quot;
          if stopping:
              return # avoid killing subprocess more than once
          stopping.append(True)
  
          info(&quot;stopping&quot;)
          self.proc.terminate() # tell the subprocess to exit
  
          # kill subprocess if it hasn't exited after a countdown
          def kill_after(countdown):
              if self.proc.poll() is None: # subprocess hasn't exited yet
                  countdown -= 1
                  if countdown &lt; 0: # do kill
                      info(&quot;killing&quot;)
                      self.proc.kill() # more likely to kill on *nix
                  else:
                      self.root.after(1000, kill_after, countdown)
                      return # continue countdown in a second
  
              self.proc.stdout.close()  # close fd
              self.proc.wait()          # wait for the subprocess' exit
              self.root.destroy()       # exit GUI
          kill_after(countdown=5)
  
  logging.basicConfig(level=logging.INFO, format=&quot;%(asctime)s %(message)s&quot;)
  root = tk.Tk()
  app = ShowProcessOutputDemo(root)
  root.protocol(&quot;WM_DELETE_WINDOW&quot;, app.stop) # exit subprocess if GUI is closed
  root.mainloop()
  info(&quot;exited&quot;)
  </code></pre>
  <p>I understand that labels do not support scrollbars but text does. Although this would be a good solution I haven't found a way to convert the current output data to text.</p>
  <p>Thanks For Reading - Connor</p>