title: Timer that prints elapsed time and resets with a button click
body: <p>I have a GUI where the user can click a button named &quot;next set&quot; that allows them to move onto the next task. I wanted to add a timer that starts as soon as they start the application and run the timer until they press the button &quot;next set&quot;. When clicked, I want the time elapsed to print and the timer to restart until they press &quot;next set&quot; button again. I would like the timer to start automatically when the code runs. Currently, the &quot;next set&quot; button has two actions, one is to retrieve the next set of images and the other action I am trying to include is to reset the timer and print time elapsed. I also only included part of the code that felt relevant because it is long.</p>
  <pre><code>import time
  import tkinter as tk
  import csv
  from pathlib import Path
  import PIL.Image
  import PIL.ImageDraw
  import PIL.ImageTk
  MAX_HEIGHT = 500
  
  IMAGES_PATH = Path(&quot;Images&quot;)
  
  CSV_LABELS_KEY = &quot;New Labels&quot;
  CSV_FILE_NAME_KEY = &quot;FolderNum_SeriesNum&quot;
  CSV_BOUNDING_BOX_KEY = &quot;correct_flip_bbox&quot;
  counter = 0
  timer_id = None
  class App(tk.Frame):
      def __init__(self, master=None):
          super().__init__(master)  # python3 style
          self.config_paths = [&quot;config 1.yaml&quot;, &quot;config 2.yaml&quot;, &quot;config 3.yaml&quot;]
          self.config_index = 0
          self.clickStatus = tk.StringVar()
          self.loadedImages = dict()
          self.loadedBoxes = dict()  # this dictionary will keep track of all the boxes drawn on the images
          self.master.title('Slideshow')
          frame = tk.Frame(self)
          tk.Button(frame, text=&quot;  Next set &quot;, command=lambda:[self.get_next_image_set(), self.reset()]).pack(side=tk.RIGHT)
          tk.Button(frame, text=&quot;  Exit  &quot;, command=self.destroy).pack(side=tk.RIGHT)
          frame.pack(side=tk.TOP, fill=tk.BOTH)
          self.canvas = tk.Canvas(self)
          self.canvas.pack()
          self._load_dataset()
  
          self.reset()
          self.start_timer = None
          t = time()
          t.start()
  
      def start_timer(self, evt=None):
          if self._start_timer is not None:
          self._start_timer = time.perf_counter()
  
      # global counter
      # counter += 1
      # label.config(text=str(counter))
      # label.after(1000, count)
  
      def reset(self):
          if self._start_timer is None:
  
          elapsed_time = time.perf_counter() - self._start_timer
          self._start_timer = None
          print('Time elapsed (hh:mm:ss.ms) {}'.format(elapsed_time))
  
  
      def _load_dataset(self):
          try:
              config_path = self.config_paths[self.config_index]
              self.config_index += 1
          except IndexError:
              return
          image_data = loadData(config_path)
          # drawing the image on the label
          self.image_data = image_data
          self.currentIndex = 0
          # start from 0th image
          self._load_image()
  
      def _load_image(self):
          imgName = self.image_data[self.currentIndex]['image_file']
          if imgName not in self.loadedImages:
  
              self.im = PIL.Image.open(self.image_data[self.currentIndex]['image_file'])
              ratio = MAX_HEIGHT / self.im.height
              # ratio divided by existing height -&gt; to get constant amount
              height, width = int(self.im.height * ratio), int(self.im.width * ratio)
              # calculate the new h and w and then resize next
              self.canvas.config(width=width, height=height)
              self.im = self.im.resize((width, height))
              if self.im.mode == &quot;1&quot;:
                  self.img = PIL.ImageTk.BitmapImage(self.im, foreground=&quot;white&quot;)
              else:
                  self.img = PIL.ImageTk.PhotoImage(self.im)
              imgData = self.loadedImages.setdefault(self.image_data[self.currentIndex]['image_file'], dict())
              imgData['image'] = self.img
              imgData['shapes'] = self.image_data[self.currentIndex]['shapes']
          # for next and previous so it loads the same image adn don't do calculations again
          self.img = self.loadedImages[self.image_data[self.currentIndex]['image_file']]['image']
          self.canvas.create_image(0, 0, anchor=tk.NW, image=self.img)
          self.show_drag_box()
  
  def loadData(fname):
      with open(fname, mode='r') as f:
          return yaml.load(f.read(), Loader=yaml.SafeLoader)
  
  
  if __name__ == &quot;__main__&quot;:
      data = loadData('config 1.yaml')
      app = App(data)
      app.pack()  # goes here
      app.mainloop()
  </code></pre>