Search code examples
pythontkinterbuttoncomboboxdisable

Having trouble getting a combobox value to enable/disable a button Python Tkinter


I have 2 comboboxes, country and year. They can change 2 different Labels each, respectively. The findbutton Button (near bottom of code) enables them to do this, using def searchget(). This works as the Labels use StringVars that change depending on what is input into the comboboxes, the def updating them by the aforementioned button. So, that part works fine. But what I continue to be perplexed by is how to stop the user from pressing the findbutton (disable it) if the combobox values selected for each or both are 0 (country = --COUNTRY-- and/or year = --YEAR--). does the .current(0) make it so that it doesn't work? I still want the default to be 0, but if the user wants to search something it has to be something else for both year and country.

Here is the entirety of my code, incase something other than the comboboxes, Labels, def or button affects it:

#!/bin/python3

#7f7f7f, #679969, #c3c3c3

#Imports
import tkinter as tk
from tkinter import ttk
from tkinter import *

#Windows
root = Tk()
root.title("GovGrants")

#Window Interface
root.geometry("400x500")
root['bg'] = "#7f7f7f"

#defs
def searchget():
    countryTitle.set(country.get())
    yearTitle.set(year.get())
    root.update()

def options():
    OPTIONS = Toplevel(root)
    OPTIONS.geometry("400x500")
    OPTIONS['bg'] = "#7f7f7f"
    optionsTitle = Label(OPTIONS, text = "Does nothing so far.\nSorry.", bg = "#c3c3c3").place(x=10, y=10)
    

#Icons and text
#root.wm_attributes('-transparentcolor', '#679969')
MainTitle = Label(root,
                  text = "Enterprise and Small Business Grants and\nSupport from the Governments (By Country)", font=("Arial Bold", 10),
                  width = 44, height = 3, borderwidth = 3, relief = "solid",
                  bg = "#c3c3c3").place(x=20, y=10)



#Buttons, dropdowns etc
    
#Combobox country
a = tk.StringVar() 
country = ttk.Combobox(root, width = 20, textvariable = a)
#w15
   
country['values'] = (' --COUNTRY--',  
                     ' Australia',  
                     ' Austria', 
                     ' Belgium', 
                     ' Canada', 
                     ' Czechia', 
                     ' Denmark', 
                     ' Estonia', 
                     ' Finland', 
                     ' France', 
                     ' Germany', 
                     ' Greece', 
                     ' Hungary',
                     ' Ireland',
                     ' Israel',
                     ' Italy',
                     ' Japan',
                     ' Korea',
                     ' Latvia',
                     ' Lithuania',
                     ' Luxembourg',
                     ' Netherlands',
                     ' New Zealand',
                     ' Norway',
                     ' Poland',
                     ' Portugal',
                     ' Slovak Republic',
                     ' Slovenia',
                     ' Spain',
                     ' Sweden',
                     ' Switzerland',
                     ' United Kingdom',
                     ' United States',
                     ' Referance Area: Non-OECD economies > Bulgaria',
                     ' Croatia',
                     ' Romania',
                     ' Russia',
                     ' South Africa') 
  
country['state'] = 'readonly'
country.place(x=80, y=70)
country.current(0)

#Combobox year
b = tk.StringVar() 
year = ttk.Combobox(root, width = 10, textvariable = b)
#w5
   
year['values'] = (' --YEAR--',    
                  ' 2002',
                  ' 2003', 
                  ' 2004', 
                  ' 2005', 
                  ' 2006', 
                  ' 2007', 
                  ' 2008', 
                  ' 2009', 
                  ' 2011', 
                  ' 2012', 
                  ' 2013', 
                  ' 2014', 
                  ' 2015', 
                  ' 2016', 
                  ' 2017', 
                  ' 2018', 
                  ' 2019', 
                  ' 2020', 
                  ' 2021', 
                  ' 2022', 
                  ' 2023') 
                           
  
year['state'] = 'readonly'
year.place(x=237, y=70) 
year.current(0)

#.get()
countryTitle = StringVar()
countryTitle.set(country.get())
yearTitle = StringVar()
yearTitle.set(year.get())

#grant actually showing
dataTitle = Label(root, text = "Data:", bg = "#7f7f7f", fg = "#FFFFFF").place(x=20, y=95)
businessSTitle = Label(root, text = "Business Stage", bg = "#7f7f7f", fg = "#FFFFFF").place(x=20, y=120)

countryTitlea = Label(root, textvariable = countryTitle, bg = "#7f7f7f", fg = "#FFFFFF").place(x=120, y=135)
yearTitlea = Label(root, textvariable = yearTitle, bg = "#7f7f7f", fg = "#FFFFFF").place(x=200, y=135)

seedTitle = Label(root, text = "Seed", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=99, y=160)
startupTitle = Label(root, text = "Start-up", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=165, y=160)
latestageTitle = Label(root, text = "Late-stage", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=232, y=160)
totalTitle = Label(root, text = "Total", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=299, y=160)
GATitle = Label(root, text = "Grant Average\n($US Million)", borderwidth = 1, relief = "solid", bg = "#c3c3c3").place(x=20, y=180)
adTitle = Label(root, text = "$", width = 9, height = 2, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=99, y=180)
bdTitle = Label(root, text = "$", width = 9, height = 2, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=166, y=180)
cdTitle = Label(root, text = "$", width = 9, height = 2, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=233, y=180)
ddTitle = Label(root, text = "$", width = 9, height = 2, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=300, y=180)

#Extra-type
businessTTitle = Label(root, text = "Business Type", bg = "#7f7f7f", fg = "#FFFFFF").place(x=20, y=230)

countryTitleb = Label(root, textvariable = countryTitle, bg = "#7f7f7f", fg = "#FFFFFF").place(x=120, y=250)
yearTitleb = Label(root, textvariable = yearTitle, bg = "#7f7f7f", fg = "#FFFFFF").place(x=200, y=250)

assistanceTitle = Label(root, text = "Assistance", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=165, y=270)
fundingTitle = Label(root, text = "Funding", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=232, y=270)
itemTitle = Label(root, text = "Business", font=("TkDefaultFont", 9), width = 9, height = 1, borderwidth = 2, relief = "solid", bg = "#c3c3c3").place(x=98, y=270)
at = Label(root, text = " \n \n \n \n \n \n \n \n", width = 9, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=166, y=290)
ft = Label(root, text = " \n \n \n \n \n \n \n \n", width = 9, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=233, y=290)
it = Label(root, text = " \n \n \n \n \n \n \n \n", width = 9, borderwidth = 1, relief = "solid", bg = "#c3c3c3", anchor="w").place(x=99, y=290)

#Buttons
optionsButton = Button(root, text = "Settings", width = 6, command = options).place(x=20, y=68)
findButton = Button(root, text = "Search", width = 6, command = searchget).place(x=329, y=68)

if country.get() == '--COUNTRY--':
    findbutton['state'] = 'disabled';

elif year.get() == '--YEAR--':
    findbutton['state'] = 'disabled';

#41 to 20 (21)
#boxes #c3c3c3

root.mainloop()

#######################################################

I've searched all over code question websites, w3schools and other "how to" websites, but nothing seems to work. I suspect it has something to do with how the combobox information is gained (I've tried country.get() = 0, country = "--COUNTRY--", country.get() = "--COUNTRY--", (there is more, but it's really just different combinations of quotation marks and common answers) pretty much every combination I possibly can.) or how the button changes state (once again, tried findbutton = "DISABLED", findbutton['state'] = 'disabled' (just different combinations of quotations and all common answers). No errors appear when I click the button, but it's like the if statement doesn't exist.

BTW: Answers not involving if-statements are also helpful, I really am just stuck and can't find a fix for this anywhere. Everything is either "disabling combobox" or "disabling button from another button", both of which don't work no matter what parts I swap and change.


Solution

  • You can bind the virtual event <<ComboboxSelected>> to the two comboboxes and update the state of findButton based on the selected values of those comboboxes inside the event callback.

    Also avoid something like below statement:

    findButton = Button(...).place(...)
    

    because findButton will be None as it is the result of .place(...).

    Required changes for your case:

    ...
    
    findButton = Button(root, text="Search", width=6, command=searchget)
    findButton.place(x=329, y=68)
    
    def check_combos(event=None):
        state = 'disabled' if (a.get() == country['values'][0] or b.get() == year['values'][0]) else 'normal'
        findButton.config(state=state)
    
    country.bind('<<ComboboxSelected>>', check_combos)
    year.bind('<<ComboboxSelected>>', check_combos)
    
    check_combos() # set button state initially
    root.mainloop()