title: Tkinter Entry StringVars can't be edited from inside a thread if they have been placed
body: <p>I have a GUI written in <code>tkinter</code>. After switching some of the elements from the <code>grid()</code> method to the <code>place()</code> method, I get an error <code>RuntimeError: main thread is not in main loop</code> and my entire GUI freezes. <a href="https://github.com/whatwareweb/homebase/blob/dev/homebase.py" rel="nofollow noreferrer">this github</a> has code that worked before, and doesn't work now. I don't know why I'm getting this error, I have not changed anything relating to editing the <code>StringVar</code>s.</p>
  <pre class="lang-py prettyprint-override"><code># GUI code.
  
  hourText = Label(timerFrame, text='Hours', bg=themebg, fg=themefg)
  minuteText = Label(timerFrame, text='Minutes', bg=themebg, fg=themefg)
  secondText = Label(timerFrame, text='Seconds', bg=themebg, fg=themefg)
  hourEntry = Entry(timerFrame, width=3, font=(&quot;Arial&quot;, 18, &quot;&quot;), textvariable=hour, bg=themebg, fg=themefg,
                    insertbackground=themefg)
  minuteEntry = Entry(timerFrame, width=3, font=(&quot;Arial&quot;, 18, &quot;&quot;), textvariable=minute, bg=themebg, fg=themefg,
                      insertbackground=themefg)
  secondEntry = Entry(timerFrame, width=3, font=(&quot;Arial&quot;, 18, &quot;&quot;), textvariable=second, bg=themebg, fg=themefg,
                      insertbackground=themefg)
  timerPauseButton = Button(timerFrame, text='Pause', command=timerPause, bg=themebg, fg=themefg)
  timerSubmit = Button(timerFrame, text='Start', command=submit, bg='blue')
  toHome = Button(timerFrame, text='Home', command=returnHome, bg='green')
  hourText.place(x=65, y=0, width=50, height=20)
  minuteText.place(x=110, y=0, width=50, height=20)
  secondText.place(x=160, y=0, width=50, height=20)
  hourEntry.place(x=65, y=25, width=50, height=40)
  minuteEntry.place(x=110, y=25, width=50, height=40)
  secondEntry.place(x=160, y=25, width=50, height=40)
  timerSubmit.place(x=135, y=65, width=75, height=30)
  timerPauseButton.place(x=65, y=65, width=75, height=30)
  toHome.place(x=110, y=95, width=50, height=30)
  
  
  # Editing the StringVar.
  
  def timerloop():
      global pauseState
      try:
          temp = int(hour.get()) * 3600 + int(minute.get()) * 60 + int(second.get())
      except:
          return
  
      while temp &gt; -1 and pauseState != 1:
          mins, secs = divmod(temp, 60)
          hours = 0
          if mins &gt; 60:
              hours, mins = divmod(mins, 60)
          hour.set(&quot;{0:2d}&quot;.format(hours))
          minute.set(&quot;{0:2d}&quot;.format(mins))
          second.set(&quot;{0:2d}&quot;.format(secs))
          time.sleep(1)
          if temp == 0 and pauseState == 0:
              hour.set('')
              minute.set('')
              second.set('')
              notification.notify(
                  title=&quot;Homebase&quot;,
                  app_icon=&quot;logo.ico&quot; if platform.system().lower() == 'windows' else 'logo.gif',
                  message=&quot;Time is up.&quot;,
                  timeout=10
              )
              sound = AudioSegment.from_file(str(alarmEntryText.get()))
              play(sound)
              pauseState = None
              exit()
          if pauseState == 0:
              temp -= 1
          if pauseState == 2:
              temp = 0
  
  
  # Creating the thread.
  
  def submit():
      if hour.get() == '':
          hour.set('0')
      if minute.get() == '':
          minute.set('0')
      if second.get() == '':
          second.set('0')
      global pauseState
      if pauseState == 1:
          pauseState = 0
      if pauseState is not None:
          timerStop()
          timerSubmit['text'] = 'Start'
          timerSubmit['bg'] = 'blue'
      else:
          timerSubmit['text'] = 'Stop'
          timerSubmit['bg'] = 'red'
          timerthread = Thread(target=timerloop)
          timerthread.start()```
  </code></pre>