Milano
Milano

Reputation: 18745

_tkinter.TclError: can't pack when trying to add ttkcalendar into tkinter GUI

I'm trying to add a ttk calendar into my Tkinter GUI. The problem is that it raises _tkinter.TclError: can't pack .34164128 inside .34161248.34161448.34161608

import Tkinter
import tkSimpleDialog

import ttkcalendar


class CalendarDialog(tkSimpleDialog.Dialog):
    """Dialog box that displays a calendar and returns the selected date"""

    def body(self, master):
        self.calendar = ttkcalendar.Calendar(master)
        self.calendar.pack()

    def apply(self):
        self.result = self.calendar.selection


# Demo code:
def main():
    root = Tkinter.Tk()
    root.wm_title("CalendarDialog Demo")

    def onclick():
        print 'click'

    cd = CalendarDialog(root)
    button = Tkinter.Button(root, text="Click me to see a calendar!", command=onclick)
    button.pack()
    root.update()

    root.mainloop()


if __name__ == "__main__":
    main()


TRACEBACK:
  File "C:/Users/Milano/PycharmProjects/MC/plots/ds.py", line 32, in <module>
    main()
  File "C:/Users/Milano/PycharmProjects/MC/plots/ds.py", line 23, in main
    cd = CalendarDialog(root)
  File "C:\Python27\lib\lib-tk\tkSimpleDialog.py", line 64, in __init__
    self.initial_focus = self.body(body)
  File "C:/Users/Milano/PycharmProjects/MC/plots/ds.py", line 9, in body
    self.calendar = ttkcalendar.Calendar(master)
  File "C:\Users\Milano\PycharmProjects\MC\plots\ttkcalendar.py", line 52, in __init__
    self.__place_widgets()      # pack/grid used widgets
  File "C:\Users\Milano\PycharmProjects\MC\plots\ttkcalendar.py", line 110, in __place_widgets
    self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1940, in pack_configure
    + self._options(cnf, kw))
_tkinter.TclError: can't pack .34164128 inside .34161248.34161448.34161608

Do you know where is the problem?

Upvotes: 2

Views: 1062

Answers (2)

Richard Williams
Richard Williams

Reputation: 31

I also encountered this problem putting a ttkCalendar into a Dialog box. I suspect the author of this post "borrowed" the same code for building a calendar as I did: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=2ahUKEwiWgYWKsJ3nAhVKl3IEHYrhCU8QFjABegQICBAB&url=https%3A%2F%2Fsvn.python.org%2Fprojects%2Fpython%2Ftrunk%2FDemo%2Ftkinter%2Fttk%2Fttkcalendar.py&usg=AOvVaw0ifTox4EI7CtBFWlRYD_m9

There are two problems I found using this code to create a Calendar object and placing it into a Dialog box. The first one causes the traceback as shown in the post. The fix is to modify the ttkcalendar.py file to pack the calendar when it is created, not after it is created using the pack() function.
Here is the diff:

102c102
<         self._calendar = ttk.Treeview(show='', selectmode='none', height=7)
---
>         self._calendar = ttk.Treeview(self, show='', selectmode='none', height=7)
109c109
<         self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
---
>         self._calendar.pack(expand=1, fill='both', side='bottom')

Once you make this change, the calendar will appear in the dialog box. However, your problems are not yet done. Another exception occurs when trying to set the minimum size of the calendar:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/home/richawil/Applications/anaconda3/envs/TLM/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "/home/richawil/Documents/Programming/Apps/TLM/TLM/ttkcalendar.py", line 134, in __minsize
    width, height = self._calendar.master.geometry().split('x')
AttributeError: 'Calendar' object has no attribute 'geometry'

I have not been able to fix this issue other than to comment out the call to self.__minsize.

63c62,63
<         self._calendar.bind('<Map>', self.__minsize)
---
>         # Commented out because _calendar object does not support geometry() function
>         #self._calendar.bind('<Map>', self.__minsize)

Upvotes: 2

TheRandomGuy
TheRandomGuy

Reputation: 337

The fault is that you don't have an __init__ method in the class CalendarDialog. So just rename the body method to __init__. Now you have initialized the instance every time one is made and a pack() method is defined.

Upvotes: 2

Related Questions