tkinter tkcalendar DateEntry inside class, did not display today's date, DateEntry outside class display today's date

84 Views Asked by At

DateEntrys which are inside the class, did not display today's date, where as DateEntry which are outside the class displays today's date.

But DateEntrys which are inside the class, printing today's date correctly.

enter image description here

# import tk modules
import tkinter as tk
from tkinter import ttk
from tkcalendar import DateEntry

class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        
        # get the system screen width and height
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        
        # application window width and height
        window_width = 430
        window_height = 115

        # display the window in center of the screen
        x = (screen_width - window_width) / 2    
        y = (screen_height - window_height) / 2

        self.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))

        # Make the window non resizable
        self.resizable(False,False)

        select_from_date = tk.StringVar()
        select_to_date = tk.StringVar() 

        dte_from_date=DateEntry(self,textvariable=select_from_date,date_pattern='dd-mm-yyyy').place(x=10,y=20)
        dte_to_date=DateEntry(self,textvariable=select_to_date,date_pattern='dd-mm-yyyy',).place(x=150,y=20)

        # print today's date correctly, but in the DateEntry, it is empty
        print(select_from_date.get())
        print(select_to_date.get())

        btn_generate = tk.Button(self, text='Generate').place(x = 10,y = 70)
        btn_settings = tk.Button(self, text='Settings').place(x = 290,y = 70)

def main():
    win = MainWindow()

    select_date = tk.StringVar()
    dte_date=DateEntry(win,textvariable=select_date,date_pattern='dd-mm-yyyy').place(x=290,y=20)

    win.mainloop()

if __name__ == '__main__':
    main()  
3

There are 3 best solutions below

1
acw1668 On BEST ANSWER

As said in comment, select_from_date and select_to_date are local variables inside __init__(), so they will be garbage collected after exiting __init__() function.

Simply change them to instance variables, self.select_from_date and self.select_to_date, to avoid garbage collection:

class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()

        # get the system screen width and height
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()

        # application window width and height
        window_width = 430
        window_height = 115

        # display the window in center of the screen
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2

        self.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))

        # Make the window non resizable
        self.resizable(False,False)

        # use instance variables instead of local variables
        self.select_from_date = tk.StringVar()
        self.select_to_date = tk.StringVar()

        DateEntry(self,textvariable=self.select_from_date,date_pattern='dd-mm-yyyy').place(x=10,y=20)
        DateEntry(self,textvariable=self.select_to_date,date_pattern='dd-mm-yyyy',).place(x=150,y=20)

        # print today's date correctly, but in the DateEntry, it is empty
        print(self.select_from_date.get())
        print(self.select_to_date.get())

        tk.Button(self, text='Generate').place(x = 10,y = 70)
        tk.Button(self, text='Settings').place(x = 290,y = 70)
0
toyota Supra On

Edit:

tkinter tkcalendar DateEntry inside class, did not display today's date, DateEntry outside class display today's date

Move those two DateEntry to main() function and comment out both prints.

Snippet:

def main():
    win = MainWindow()
    select_from_date = tk.StringVar()
    select_to_date = tk.StringVar() 

    select_date = tk.StringVar()
    dte_date=DateEntry(win,textvariable=select_date,date_pattern='dd-mm-yyyy').place(x=290,y=20)
    dte_from_date=DateEntry(win,textvariable=select_from_date,date_pattern='dd-mm-yyyy').place(x=10,y=20)
    dte_to_date=DateEntry(win,textvariable=select_to_date,date_pattern='dd-mm-yyyy',).place(x=150,y=20)

    win.mainloop()

Screenshot:

enter image description here

0
Ravi Kannan On

Thanks toyota Supra. I modified code with extra function PlaceWidget and pass two variables as parameters as below. It is working fine.

# import tk modules
import tkinter as tk
from tkinter import ttk
from tkcalendar import DateEntry

select_from_date = tk.StringVar()
select_to_date = tk.StringVar()
    
class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        
        # get the system screen width and height
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        
        # application window width and height
        window_width = 430
        window_height = 115

        # display the window in center of the screen
        x = (screen_width - window_width) / 2    
        y = (screen_height - window_height) / 2

        self.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))

        # Make the window non resizable
        self.resizable(False,False)

    def PlaceWidget(self,select_from_date,select_to_date):     
    
        dte_from_date=DateEntry(self,textvariable=select_from_date,date_pattern='dd-mm-yyyy').place(x=10,y=20)
        dte_to_date=DateEntry(self,textvariable=select_to_date,date_pattern='dd-mm-yyyy',).place(x=150,y=20)        

        btn_generate = tk.Button(self, text='Generate').place(x = 10,y = 70)
        btn_settings = tk.Button(self, text='Settings').place(x = 290,y = 70)
        
def main():
    win = MainWindow()
    select_from_date = tk.StringVar()
    select_to_date = tk.StringVar()
    
    win.PlaceWidget(select_from_date,select_to_date)

    print(select_from_date.get(),select_to_date.get())
    
    select_date = tk.StringVar()
    dte_date=DateEntry(win,textvariable=select_date,date_pattern='dd-mm-yyyy').place(x=290,y=20)
        
    win.mainloop()

if __name__ == '__main__':
    main()