Ame
Ame

Reputation: 93

Combobox don't show in tkinter

Good day everyone, I'm trying to create comboboxes to input some date, it worked for a while but, I don't know why, it stopped appearing in my frame and I'm not able to fix it. I was also wondering a couple things more: is it possible to have the input of the day with a 0 (like 01, 02 etc) and also to use something like range for the day of the months instead of writing all of them. I cannot do either since I always get errors when I try. Thank for your help!

import tkinter as tk
from tkinter import *
import tkinter.ttk

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

###BIRTHDAY
        birthday_label = tk.Label(self, text="Birthday:", font=('times', 14), anchor='e')
        birthday_label.grid(row=3, sticky='e')

        month_day = {
            'January': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                        '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'February': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                         '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29'],
            'March': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                      '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'April': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                      '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'May': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                    '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'June': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                     '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'July': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                     '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'August': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                       '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'September': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                          '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'October': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '11', '12', '13', '14', '15', '16', '17', '18',
                        '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'November': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '11', '12', '13', '14', '15', '16', '17', '18',
                         '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'December': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                         '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31']}

    def getUpdateData(self, event):
        self.day['values'] = month_day[self.month.get()]

        self.day = IntVar(self)
        self.day.set(1)
        self.day = ttk.Combobox(self)
        self.day.grid(row=3, column=1)

        self.month = IntVar(self)
        self.month.set("January")
        self.month = ttk.Combobox(self, values=list(month_day.keys()))
        self.month.bind('<<ComboboxSelected>>', self.getUpdateData)
        self.month.grid(row=3, column=1, sticky='w')

        self.year = IntVar(self)
        self.year.set(2000)
        self.year = ttk.Combobox(self, values=list(range(1940, 2006)))
        self.year.grid(row=3, column=1, sticky='e')


if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

Upvotes: 2

Views: 849

Answers (2)

OysterShucker
OysterShucker

Reputation: 5541

Ok, here we go. These are the things that are wrong with your script:

  1. You are creating IntVars and then basically saying "nevermind be a combobox instead" *Comboboxes accept StringVar but you don't need them
  2. You are creating all your widgets in your update method, and even though that is strange, you never bothered to call the update method so it would create any of it.
  3. Numerous things are written in a far too verbose way
  4. You should call grid_rowconfigure and grid_columnconfigure to finalize the grid configuration.
  5. The only thing that needs to be updated is the amount of days you can select when a new month is selected. It is up to you to implement leap years.

I completely rewrote your script and changed everything. The way my version is displayed may not be exactly what you want, but it would be easy enough for you to customize that part now that everything works.

# quick and dirty
from tkinter.ttk import *
from tkinter import *

class Application(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self,  *args, **kwargs)
        
        # ranges are your friend
        d29 = list(range(1,30))
        d30 = list(range(1,31))
        d31 = list(range(1,32))
        
        #
        self.months = dict(
            January     = d31,
            February    = d29,
            March       = d31,
            April       = d30,
            May         = d31,
            June        = d30,
            July        = d31,
            August      = d31,
            September   = d30,
            October     = d31,
            November    = d30,
            December    = d31)

        self.lbl_birth = Label(self, text="Birthday:", font=('times', 14))
        self.lbl_birth.grid(row=1, column=1)
        
        self.cb_day = Combobox(self, values=self.months["January"])
        self.cb_day.grid(row=1, column=2)
        self.cb_day.set("1")
        
        self.cb_month = Combobox(self, values=[*self.months])
        self.cb_month.bind('<<ComboboxSelected>>', self.update)
        self.cb_month.grid(row=1, column=3)
        self.cb_month.set("January")
        
        self.cb_year = Combobox(self, values=list(range(1996, 2006)))
        self.cb_year.grid(row=1, column=4)
        self.cb_year.set("2000")
        
        # configure grid
        # this app does not need this configuration BUT you eventually will
        # so why not get used to it right now
        items = [self.lbl_birth, self.cb_day, self.cb_month, self.cb_year]
        for t in items:
            self.grid_columnconfigure(t, weight=1)
            self.grid_rowconfigure(t, weight=1)
        
    def update(self, event):
        # set day values to the appropriate range
        self.cb_day["values"] = self.months[self.cb_month.get()]
        self.cb_day.set("1")


if __name__ == "__main__":
    app = Application()
    app.title('My Birthday App')
    app.mainloop()

Upvotes: 1

micah
micah

Reputation: 21

You might want to create all the things in the __init__ method. You are trying to create the combo boxes in the getUpdateData method, which doesn't get called, so they don't get created.

I took out the initial variables self.day=IntVar(self) etc because you just overwrote them anyway, so they weren't doing anything. If you want to put them back you can, but name the combo boxes and the tkinter variables differently.

When you define the month,

        self.month = IntVar(self)
        self.month.set("January")

you will get an error because "January" is not an int. Use self.month = StringVar(self) instead.

Here is a working example with the combo boxes showing:

import tkinter as tk
from tkinter import *
import tkinter.ttk as ttk

class MainApplication(tk.Frame):

    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

###BIRTHDAY
        birthday_label = tk.Label(self, text="Birthday:", font=('times', 14), anchor='e')
        birthday_label.grid(row=3, sticky='e')

        month_day = {
            'January': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                        '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'February': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                         '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29'],
            'March': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                      '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'April': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                      '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'May': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                    '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'June': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                     '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'July': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
                     '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'August': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                       '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'September': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                          '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'October': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '11', '12', '13', '14', '15', '16', '17', '18',
                        '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
            'November': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '11', '12', '13', '14', '15', '16', '17', '18',
                         '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
            'December': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
                         '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31']}

        self.month_cb = ttk.Combobox(self, values=list(month_day.keys()))
        self.month_cb.bind('<<ComboboxSelected>>', self.getUpdateData)
        self.month_cb.grid(row=1, column=1, sticky='w')
        self.month_cb.set("January")
        
        self.day_cb = ttk.Combobox(self)
        self.day_cb['values'] = month_day[self.month_cb.get()]
        self.day_cb.set(1)
        self.day_cb.grid(row=2  , column=1)

        self.year_cb = ttk.Combobox(self, values=list(range(1940, 2006)))
        self.year_cb.grid(row=3, column=1, sticky='e')
        self.year_cb.set(2000)
    def getUpdateData():
            pass        


if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

Upvotes: 1

Related Questions