title: Yes/No checkbutton for bool attribute in a GUI to manage a list of objects
body: <p>For this gui I have five objects: Full name, Contact info, Desired Language, Difficulty level, and Experience with the language. My design for this assignment is that it's a simple 'Foreign Language Bookstore Request Manager' in which I can add, edit and delete requests for foreign language books. </p>
  
  <p>I want the first four objects to be Entry fields and then the fifth (experience) to be a checkbox, for this data attribute I want to make it a bool representing yes/no state for the question of whether one has experience with the language they are requesting. </p>
  
  <p>From my textbook and previous examples I was able to make a basic y/n checkbox, however it appears at the top of my window and I am stuck on how to write it so that the experience data attribute is a check button for the bool attribute rather than an Entry form and that whatever is selected (yes or no/whether it is true or false) appears when I use a <em>str</em> method to display each attribute's value using ListboxSelect. </p>
  
  <p>When I have tried to separate the fifth attribute from the rest so that it is a checkbox rather than Entry form, I cannot run my program, and in trying to create the bool attribute I ran into errors as well and was unsure whether I need to fix the bool attribute first or the checkbox, whether they go hand in hand, etc</p>
  
  <p>My questions are: 
  1) Am I using the correct formatting to create the y/n checkbox for the bool attribute? 
  2) How do I write the checkbox so that it appears next to the experience label and is not an Entry form as it is currently written? </p>
  
  <p>I apologize if this is woefully stupid to ask, however I have spent 7 hours trying to troubleshoot these issues and haven't figured out what I am doing wrong and how to correct and add what is necessary to round out this program. </p>
  
  <p>Unrelated to the check button, with the ListboxSelect widget, it is showing the object at the address I am looking for, but not actually displaying what I had thought I had written which would show:
  'Full Name: , Contact info: , Language: , Difficulty: , Experience with language: (then here would be the answer to the checkbox for the boolean attribute which I haven't figured out yet)' in the Book Requests section of my program. I am including a picture of my program and current problems as well as some of the code. <a href="https://i.stack.imgur.com/m1w8k.png" rel="nofollow noreferrer">does not display what I had thought I had written</a> </p>
  
  <pre><code>import tkinter
  import request
  
  class Application:
      def __init__(self):
          self.__requests = []
          self.__selected_index = 0
          self.__selected_request = None
  
          self.__window = tkinter.Tk()
          self.__window.title('Foreign Language Bookstore Request Manager')
  
          self.__full_name = tkinter.StringVar()
          self.__contact_info = tkinter.StringVar()
          self.__language = tkinter.StringVar()
          self.__difficulty = tkinter.StringVar()
          self.__experience = tkinter.StringVar()
  
          self.cb_var1 = tkinter.IntVar()
          self.cb_var2 = tkinter.IntVar()
  
          self.cb_var1.set(0)
          self.cb_var2.set(0)
  
          self.cb1 = tkinter.Checkbutton(self.__window, \
                                         text='Yes', variable=self.cb_var1)
          self.cb2 = tkinter.Checkbutton(self.__window, \
                                         text='No', variable=self.cb_var2)
  
          self.cb1.pack()
          self.cb2.pack()
  
  
  
          self.build_input_frame('Full Name: ', self.__full_name)
          self.build_input_frame('Contact info (phone, email): ', self.__contact_info)
          self.build_input_frame('Desired language: ', self.__language)
          self.build_input_frame('Difficulty level 1- beginner, 2- intermediate, 3- advanced: ', self.__difficulty)
          self.build_input_frame('Experience with language? ', self.__experience)
  
          frame = tkinter.Frame(self.__window)
          self.__add_button = tkinter.Button(frame, text='Add Request',
              anchor=tkinter.W, command=self.add_request)
          self.__add_button.pack(side='left')
          self.__save_button = tkinter.Button(frame, text='Save Request',
              anchor=tkinter.W, command=self.save_request, state=tkinter.DISABLED)
          self.__save_button.pack(side='left')
          self.__delete_button = tkinter.Button(frame, text='Delete Request',
              anchor=tkinter.W,
              command=self.delete_request, state=tkinter.DISABLED)
          self.__delete_button.pack()
          frame.pack()
  
          frame = tkinter.Frame(self.__window)
          label = tkinter.Label(frame, text='Book Requests')
          self.__requests_list = tkinter.Listbox(frame, width=80,
              selectmode=tkinter.SINGLE)
  
          self.__requests_list.bind('&lt;&lt;ListboxSelect&gt;&gt;', self.select_request)
          label.pack()
          self.__requests_list.pack()
          frame.pack()
  
      def build_input_frame(self, label, textvariable):
          """Build the top frames of the window for being able to enter data."""
          frame = tkinter.Frame(self.__window)
          label = tkinter.Label(frame, text=label, width=50, anchor=tkinter.W)
          entry = tkinter.Entry(frame, textvariable=textvariable, width=30)
          label.pack(side='left')
          entry.pack(side='right')
          frame.pack()
  
      def add_request(self):
          """Get the values from the bound variables and create a new Request."""
          r = request.Request(self.__full_name.get(), self.__contact_info.get(),
              self.__language.get(), self.__difficulty.get(),
                              self.__experience.get())
          self.__requests.append(r)
  
          self.__requests_list.insert(tkinter.END, str(r))
  
      def select_request(self, event):
          """Get the Request at the index selected, and set the Entry fields
             with its values."""
          # Get the current selection from the Listbox. curselection() returns
          # a tuple and we want the first item
          # Get the current selection from the Listbox. curselection() returns
          # a tuple and we want the first item
          current_selection = self.__requests_list.curselection()
          if current_selection:
              self.__selected_index = current_selection[0]
  
              # Grab the Request object from self.__request at that index
              self.__selected_request = self.__requests[self.__selected_index]
  
              # Use it's values to set the StringVars
              self.__full_name.set(self.__selected_request.get_full_name())
              self.__contact_info.set(self.__selected_request.get_contact_info())
              self.__language.set(self.__selected_request.get_language())
              self.__difficulty.set(self.__selected_request.get_difficulty())
              self.__experience.set(self.__selected_request.get_experience())
  
              # Make sure the Save button is enabled
              self.__save_button.config(state=tkinter.NORMAL)
              self.__delete_button.config(state=tkinter.NORMAL)
  
  
      def delete_request(self):
          """Remov the Request at the index selected then set the Entry fields
             to empty values."""
          if 0 &lt;= self.__selected_index &lt; len(self.__requests):
              del self.__requests[self.__selected_index]
              self.__requests_list.delete(self.__selected_index)
  
              # Call the method to deselect the item, clear Entry fields, and
              # disable buttons.
              self.after_selected_operation()
  
      def save_request(self):
          """Set the selected Request's fields and then persist its __str__
             representation to the Listbox."""
          self.__selected_request.set_full_name(self.__full_name.get())
          self.__selected_request.set_contact_info(self.__contact_info.get())
          self.__selected_request.set_language(self.__language.get())
          self.__selected_request.set_difficulty(self.__difficulty.get())
          self.__selected_request.set_experience(self.__experience.get())
  
          # Listbox widgets don't have a way of updating an item in place. So
          # We'll delete the item at a particular index and then add it
          self.__requests_list.delete(self.__selected_index)
          self.__requests_list.insert(self.__selected_index,
              str(self.__selected_request))
  
          # Call the method to deselect the item, clear Entry fields, and
          # disable buttons.
          self.after_selected_operation()
  
      def after_selected_operation(self):
          """Clear the selected index, request, and disable buttons."""
          self.__selected_index = -1
          self.__selected_request = None
  
          self.__full_name.set('')
          self.__contact_info.set('')
          self.__language.set('')
          self.__difficulty.set('')
          self.__experience.set('')
  
          # Make sure the Save and Delete buttons are disabled
          self.__save_button.config(state=tkinter.DISABLED)
          self.__delete_button.config(state=tkinter.DISABLED)
  </code></pre>