title: Can't make tkinter checkbutton work normally when running as script
body: <p>I defined a tkinter checkbutton widget to create check boxes based on a user defined list and return a new list including the selected elements. It works as expected when I run it directly on IPython console (I use Spyder3 most of the time). It also works if I save the function as a Python script and call it as a module's function in Python console. However, if I run the script containing this function, it behaves weird that all the change of those check buttons will not reflect to the real value at all; all of the values are <strong>False</strong> no matter what items I selected. The followings are the code and example: </p>
  
  <p><strong>CheckBox.py</strong> :</p>
  
  <pre><code>import tkinter as tk
  from tkinter.messagebox import askyesno
  import sys
  
  def CheckBox(picks, *Args):
      class checkboxfromlist(tk.Frame):
          def __init__(self, parent, picks):
              tk.Frame.__init__(self, parent)
              self.vars = []
              for pick in picks:
                  var = tk.BooleanVar()
                  chk = tk.Checkbutton(self, text=pick, variable=var, onvalue=True, offvalue=False)
                  chk.pack()
                  self.vars.append(var)
  
          def state(self):
              return list(map((lambda var: var.get()), self.vars))
  
      class MainWindow(tk.Tk):
          def __init__(self, picks, text):
              tk.Tk.__init__(self)
              self.resizable(width=False, height=False)
              self.title('Select desired download')
              self.protocol('WM_DELETE_WINDOW', self.on_exit)
              self.l = tk.Label(self, text='Please select desired download {}'.format(text))
              self.l.pack()
              self.ChkBox = checkboxfromlist(self, picks)
              self.ChkBox.pack()
              self.Button = tk.Button(self, text='Ok', width=40, height=2, command=self.quit)
              self.Button.pack()
              # Make popup window at the centre
              self.update_idletasks()
              w = self.winfo_screenwidth()
              h = self.winfo_screenheight()
              size = tuple(int(_) for _ in self.geometry().split('+')[0].split('x'))
              x = w/2 - size[0]/2
              y = h/2 - size[1]/2
              self.geometry('%dx%d+%d+%d' % (size + (x, y)))
  
          def on_exit(self):
          # When you click x to exit, this function is called
              if askyesno("Exit", "Do you want to quit the application?"):
                  self.destroy()
                  sys.exit(0)
  
      text = ' for '.join(Args)
      App = MainWindow(picks, text)
      App.mainloop()
      mask = App.ChkBox.state()
      App.destroy()
      selected = [item for index, item in enumerate(picks) if mask[index]]
      return selected
  </code></pre>
  
  <p>Here is the snapshot of the widget:
  <a href="https://i.stack.imgur.com/0FcSM.png" rel="nofollow noreferrer">widget screenshot</a></p>
  
  <p>These work:  </p>
  
  <ol>
  <li>Paste the code directly in IPython console then run
  <strong>CheckBox(MyList, 'item')</strong>   </li>
  <li>Input <em>Python</em> in terminal, then <em>import CheckBox</em>, run <strong>CheckBox.CheckBox(MyList, 'item')</strong></li>
  </ol>
  
  <p>These don't work:  </p>
  
  <p>Run as a script either in spyder, terminal, or double-click  </p>
  
  <pre><code>if __name__ == '__main__':
      CheckBox(MyList, 'item')
  </code></pre>
  
  <p>Run as a external module in a script in spyder, terminal, or
      double-click</p>
  
  <pre><code>import CheckBox
  if __name__ == '__main__':
      CheckBox.CheckBox(MyList, 'item')
  </code></pre>
  
  <p>I tried using Python 3.5.2 on Ubuntu and 3.6.4 on Windows 10 and both of them gave me the same problem. I have spent whole day figuring out what was going on but with no luck. Any comment would be very much appreciated.</p>
  
  <p><strong><em>Edit</em></strong>:<br>
  I found that the widget works until I add the following code at the beginning of the main function:  </p>
  
  <pre><code>root = tk.Tk()
  root.withdraw()
  </code></pre>
  
  <p>The reason I do so is because there will be some user prompt widget later during the process. Without <em>root.withdraw()</em>, there will be always a blank window on the screen. The effect of the above code last until I restart Spyder3; this means I can't make my code work again by simply delete the above code. Here's the snapshots of the program:  </p>
  
  <p>This works:<br>
  <a href="https://i.stack.imgur.com/Z0Ida.png" rel="nofollow noreferrer">Screenshot of Spyder</a>  </p>
  
  <p>As you can see, the print out list is exactly the items I selected (I run it once then run it again to take the snapshot of the widget).  </p>
  
  <p>This doesn't:<br>
  <a href="https://i.stack.imgur.com/bjS4b.png" rel="nofollow noreferrer">Screenshot of Spyder</a></p>
  
  <p>The print out list is empty no matter how I selected the items.  </p>
  
  <p><strong><em>PS</em></strong>: <strong>fuck_tk</strong> is exactly the same as <strong>CheckBox.py</strong> I post above.  </p>
  
  <p><strong><em>Edit2</em></strong>:<br>
  I found out that in order to make all the widget works without showing the blank main tkinter window, I need to make all of my tkinter messageboxes as individual functions as below:  </p>
  
  <pre><code>def User_Confirm():
      root = tk.Tk()
      root.withdraw()
      answer = askquestion('test', 'tkinter sucks')
      root.destroy()
      return answer
  </code></pre>
  
  <p>However, this workaround sound very stupid to me. Is there any elegant way to hide the main tkinter window while not influence the functionality of my CheckBox widget?  </p>