pythonttkpython-classttkbootstrapttkcombobox

How to add class variable values to a list, python 3x?


I'm trying to add class variable values to a list inside a function, but I'm not seeing any errors or the expected output? The comboxbox doesn't display when I uncomment the list code.

Outside of the function, this code works standalone:

value_list = []
selected_float = 0.5
value_list.append(selected_float)
print('The value_list value is: ')
print(value_list)

Output as expected: The value_list value is: [0.5]

However, here is the code with the function where it doesn't print anything. I had to comment out the code at 1. and 2. or it stopped working and didn't display the combobox.

from tkinter import *
from tkinter import ttk

# Create an instance of tkinter frame or window
win = Tk()

# Set the size of the window
win.geometry("700x350")

# Create a function to clear the combobox
def clear_cb(self):
   self.cb.set('')
   
def handle_selection(self):
    selected_index = self.cb.current()  # Get the index of the selected item
    print(selected_index)
    selected_tuple = self.data[selected_index]  # Get the selected tuple
    print(selected_tuple)
    selected_float = float(selected_tuple[-1])  # Extract the float value from the tuple
    print(selected_float)  # Print the extracted float value
    
    # 2. Commented out these lines:
    #self.value_list.append(selected_float)
    #print('The value_list value is: ')
    #print(self.value_list)

class ComboWidget():
    def __init__(self):
        
        # Create a combobox widget
        self.var = StringVar()
        self.cb = ttk.Combobox(win, textvariable= self.var)
        self.cb['values'] = self.data
        self.cb['state'] = 'readonly'
        self.cb.pack(fill = 'x',padx=5, pady=5)
        
        # Define  Tuple
        self.data = [('First', 'F', '0.5'), ('Next', 'N', '1.0'), ('Middle', 'M', '0.6'), ('Last', 'L', '0.24')]
       
        # 1. Commented out the declaration.
        #self.value_list = []

        self.cb.bind("<<ComboboxSelected>>", handle_selection)
    
        # Create a button to clear the selected combobox text value
        self.button = Button(win, text= "Clear", command= clear_cb)
        self.button.pack()

win.mainloop()

I believe it should be possible to mix instance and class variables together, but something I'm doing is wrong? Any ideas?


Solution

  • I'm not a big Tkinter user, but I have battled with it enough in the past to get your code working!

    from tkinter import *
    from tkinter import ttk
    
    # Create an instance of tkinter frame or window
    win = Tk()
    
    # Set the size of the window
    win.geometry("700x350")
    
    
    
    class ComboWidget():
        def __init__(self):
            
            # Create a combobox widget
            self.var = StringVar()
            self.cb = ttk.Combobox(win, textvariable= self.var)
            # Define  Tuple
            self.data = [('First', 'F', '0.5'), ('Next', 'N', '1.0'), ('Middle', 'M', '0.6'), ('Last', 'L', '0.24')]
    
            self.cb['values'] = self.data
            self.cb['state'] = 'readonly'
            self.cb.pack(fill = 'x',padx=5, pady=5)
            
           
            # 1. Commented out the declaration.
            self.value_list = []
    
            self.cb.bind("<<ComboboxSelected>>", self.handle_selection)
        
            # Create a button to clear the selected combobox text value
            self.button = Button(win, text= "Clear", command= self.clear_cb)
            self.button.pack()
    
        # Create a function to clear the combobox
        def clear_cb(self):
           self.cb.set('')
           
        def handle_selection(self, _):
            selected_index = self.cb.current()  # Get the index of the selected item
            print(selected_index)
            selected_tuple = self.data[selected_index]  # Get the selected tuple
            print(selected_tuple)
            selected_float = float(selected_tuple[-1])  # Extract the float value from the tuple
            print(selected_float)  # Print the extracted float value
            
            # 2. Commented out these lines:
            self.value_list.append(selected_float)
            print('The value_list value is: ')
            print(self.value_list)
    
    c=ComboWidget()
    win.mainloop()
    

    It could still use some tidying up, but I hope this gets you back on track. Here were some of the issues:

    1. As @meshkati commented, you actually have to instantiate ComboWidget.

    2. As @OneCricketeer commented, the two functions you defined were actually written as methods of ComboWidget and therefore belong in the body of the class.

    3. Your definition of self.data needs to precede its first use

    4. handle_selection and clear_cb needed to be prefixed by 'self.' where they are bound to methods

    5. The self.handle_selection method should have 2 paramaters: self because it is a method, and an event. Because you don't actually use the event passed in, you can just put '_'

    I think that's it - good luck with your further development of this project!