TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
10.88k stars 1.02k forks source link

Binding Comboboxes in CTk v5.1 #1609

Open vmasc99 opened 1 year ago

vmasc99 commented 1 year ago

Hello, although I have seen how the .bind() method was added in v5.0.0, I still have issues with binding a command to a dropdown menu click. The function bound to the click does not start.

To be more specific, it is an event based, dependant dropdown, and the bind is so defined, as I modeled on Tk:

dropdown.bind("<<ComboboxSelected>>", second_dp).

There must be some further compatibility issues between CTk and Tk since even another dropdown dependency method I found here https://stackoverflow.com/questions/59066179/drop-down-list-dependent-from-another-drop-down-tkinter works on Tk as intended, which isn't true for CTk.

I have tried to reproduce the issue here in small scale, but this time it doesn't work on CTk for some other reason. Anyway this works in Tk:

import tkinter as tk              
from tkinter import ttk

machines = [1,2,3,4,5,6,7]

def add_dropdown():

                        new_dropdown = ttk.Combobox(window, values=machines,textvariable = txt)

                        new_dropdown.grid(row=3, column=0)

                        dropdowns.append(new_dropdown)

                        hp_dropdown = ttk.Combobox(window, values = [''])
                        hp_dropdown.grid(row = 3, column = 1)

                        new_dropdown.bind("<<ComboboxSelected>>", create)
                        new_dropdown.bind("<<ComboboxSelected>>", second_dp)

def second_dp(event):
                        last_dropdown = dropdowns[-1]
                        if event.widget == last_dropdown:
                            add_dropdown()
                            hp_dropdown = ttk.Combobox(window, values = [5,4,53,3,2,2,4,4],
                                                       textvariable= hp)
                            hp_dropdown.grid(row = 3, column = 1)
                            #hp_dropdown.config(value = list(data[data['name']== txt.get() ]['power']))
                            hp_dropdown.bind("<<ComboboxSelected>>", add_dropdown)

def create():
                   add_dropdown()

window = tk.Tk()

window.title("Calculator")

window.geometry("800x500")

reset_button = tk.Button(window, text="Create", command=create)

reset_button.grid(row=1, column=3)

txt = tk.StringVar()                 
hp = tk.IntVar()                    
e1 = tk.IntVar()                  
e2 = tk.DoubleVar()                   
counter = tk.IntVar(value = 0)

dropdowns = []                    
entrys = []              
labels = []                   
values= [0]

window.mainloop()

If anyone knows how to fix this or work around it, I'd be great.

gaveone commented 1 year ago

Hopefully, there are no mistakes, however, I'm experiencing the same problem (I'm a novice).

import tkinter  as tk
from tkinter import ttk
import customtkinter as ttkX

# make window
window = ttkX.CTk()
window.geometry('500x500')
window.title('another')

listV = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',)
goods=tk.StringVar(value= listV[0])
combobox = ttkX.CTkComboBox(
     window,
     variable=goods
)
combobox.configure(values=listV)
combobox.pack()

# Event
combobox.bind('<<ComboboxSelected>>', lambda event:print('selected'))

 window.mainloop()
vmasc99 commented 1 year ago

Yeah it looks like to me that the command is not being bound in this case as well.

DDuran19 commented 1 year ago

Just want to up this as I am also experiencing the same thing

self.course = CTk.CTkComboBox(self.entry_frame,width=350,values=self.course_dropdown)
self.course.grid(row=4,column=self.column_entry,padx=5,sticky="e")
self.course.bind('<KeyPress>',lambda event: self.invalid_input_on_combobox(event=event,combobox=self.course,dropdown=self.course_dropdown))
self.course.bind('<<ComboboxSelected>>',lambda event: self.invalid_input_on_combobox(event=event,combobox=self.course,dropdown=self.course_dropdown))
CrawfordJohn commented 1 year ago

Was having the same issue. Was able to fix by binding a mouse button click to the canvas object of the combobox, here:

self.model_input._canvas.bind("<Button-1>", bind_function)

In my program, I wanted a new widget to be created based on the value of the combobox. Unfortunately, this bind function would be called before the value of the combobox was updated. In order to fix this, I used the "after" command, to create the new widget after a small lapse of time so that the value of the combobox would update and the code would work properly.

    def bind_function(event):
        def on_select():
            if self.model_input.get() != 'mean' and self.model_input.get() != '':
                self.system_input = ctk.CTkComboBox(self.forecast_tab, state="readonly", values=system_dict[self.model_input.get()])

                system_label.grid(row=1, column=0, pady=5)
                self.system_input.grid(row=1, column=1, pady=5)
            else:
                system_label.grid_forget()
                try:
                    self.system_input.grid_forget()
                except AttributeError:
                    pass

        self.after(100, on_select_again) #time delay
EminGul commented 1 year ago

The above didn't work for me. I was able to solve this issue by using the command parameter for CTkCombobox instead of bind as seen here: https://stackoverflow.com/questions/72567680/tkinter-combobox-variable-issue.

soluentre commented 2 months ago

Same, here, my code is:

self.selectreport = ctk.CTkComboBox(self, variable=report, height=30, font=('Roboto', 14))
self.selectreport.configure(values=['Please select a Database to continue ... '])
self.selectreport.grid(row=2, column=0, columnspan=4, padx=5, pady=(0, 15), sticky="new")
self.selectreport.bind("<<ComboboxSelected>>", on_select)