Tkinter Calendar doesn't grid at the right place

520 Views Asked by At

So i'm working at minimal application that contains a DateEntry, but im having trouble at griding the widget at the right place, it should be packed inside of the container that's holding other inputs, but actually it's been grided at the bottom of the page.

Below there's the actual code of the view. Im not understanding why this is happening, but i think that's probably something with the DateEntry class that im inhereting in class MyDateEntry(DateEntry).

import tkinter as tk
from tkinter import ttk
from tkcalendar import DateEntry
from datetime import date


class View(tk.Tk):
    PAD = 10

    LABELS_LIST = [
        'Selecione o estado: ',
        'Digite o municipio: ', 
        'Selecione o dia: ',
        'Digite a temperatura máxima: ',
        'Digite a temperatura minima: '
    ]

    STATE_LIST = [
        'AC',
        'AL',
        'AP',
        'AM',
        'BA',
        'CE',
        'DF',
        'ES',
        'GO',
        'MA',
        'MT',
        'MS',
        'MG',
        'PA',
        'PB',
        'PR',
        'PE',
        'PI',
        'RJ',
        'RN',
        'RS',
        'RO',
        'RR',
        'SC',
        'SP',
        'SE',
        'TO'
    ]

    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        self.title('EToCalc1.0')
        self.temp_max_var = tk.StringVar()
        self.temp_min_var = tk.StringVar()
        self._change_style()
        self._make_main_frm()
        self._make_labels()
        self._make_combobox_state()
        self._make_city_entry()
        self._make_calendar()
        self._make_max_temp_entry()

    def main(self):
        self.mainloop()

    def _make_main_frm(self):
        self.main_frm = ttk.Frame(self)
        self.main_frm.pack(padx=self.PAD, pady=self.PAD)

    def _make_city_entry(self):
        frm = ttk.Frame(self.outer_frm)
        frm.grid()
        self.city_entry = ttk.Entry(frm)
        self.city_entry.pack(pady=self.PAD, padx=self.PAD)

    def _make_calendar(self):
        frm = ttk.Frame(self.outer_frm)
        frm.grid()
        self.de = MyDateEntry(frm)
        self.de.pack(pady=self.PAD, padx=self.PAD)

    def _change_style(self):
        style = ttk.Style(self)
        style.theme_use('clam')

    def _make_labels(self):
        frm = ttk.Frame(self.main_frm)
        frm.grid(row=0,column=0)
        i = 0
        for item in self.LABELS_LIST:
            label = ttk.Label(frm, text=item)
            label.grid(row=i, column=0, padx=self.PAD,pady=self.PAD)
            i += 1

    def _make_combobox_state(self):
        self.outer_frm = ttk.Frame(self.main_frm)
        self.outer_frm.grid(row=0, column=1)
        frm = ttk.Frame(self.outer_frm)
        frm.grid()
        self.state_combobox = ttk.Combobox(frm, values=self.STATE_LIST)
        self.state_combobox.pack(pady=self.PAD, padx=self.PAD)
        self.state_combobox.set(value='Escolha um estado')

    def _make_max_temp_entry(self):
        frm = ttk.Frame(self.outer_frm)
        frm.grid()
        temp_max_entry = ttk.Entry(frm, textvariable=self.temp_max_var)
        temp_min_entry = ttk.Entry(frm, textvariable=self.temp_min_var)
        temp_max_entry.pack(padx=self.PAD, pady=self.PAD)
        temp_min_entry.pack(padx=self.PAD, pady=self.PAD)
        


class MyDateEntry(DateEntry):
    def __init__(self, master=None, **kw):
        DateEntry.__init__(self, master=None, **kw)
        # add black border around drop-down calendar
        self._top_cal.configure(bg='black', bd=1)
        # add label displaying today's date below
        tk.Label(self._top_cal, bg='gray90', anchor='w',
            text='Hoje: %s' % date.today().strftime('%d/%m/%Y')).pack(fill='x')

There's the printscreen of the window, note that the DateEntry is at the bottom

Thank you!

SOLUTION

Thanks to @jasonharper who commented the solution, as quoted:

DateEntry.__init__(self, master=None, **kw) - you are throwing away the master parameter being passed to your class, and instead explicitly passing None to the superclass (making the widget a child of the root window instead).>

So i just removed the =None from master=None and the correct frame is passing as argument.

Thank you @jasonharper!

1

There are 1 best solutions below

0
On

You are explicitly forcing the widget to be in the root window with master=None in this line of code:

DateEntry.__init__(self, master=None, **kw)

Instead, you should be passing in the value of master that was passed in by the caller:

DateEntry.__init__(self, master, **kw)