1

I am using a calendar widget for Python. And I need to call the widget when a button is clicked. The situation is that I cannot find what is the method in the calendar class that displays the widget itself. The calendar class was taken from here: http://www.eurion.net/python-snippets/snippet/Calendar_Date%20picker.html

Here are my imports:

from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import time
import requests #needs to be installed
import pymysql #needs to be installed
import csv 
import win32com.client #needs to be installed
from calendar import Calendar
import datetime

Here is the button creation:

# Calendar Buttons
calBut=ttk.Button(f2, width=4, text="Cal",       command=Calendar.what_method?).grid(column=3,row=1, sticky=W)

As far as I know, I can just set the command of the button to call the widget display method located in the calendar class. How to get the method that displays the calendar widget each time my button is clicked? None of the ones showing are displaying the widget.

Using Python 3.3.5 Spider WinPython 3.3.5

**EDIT**

The program has tabs and the f2 indicates the tab where the button will be.

from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import time
import requests #needs to be installed
import pymysql #needs to be installed
import csv 
import win32com.client #needs to be installed
import datetime
from calendar import Calendar
import calendar


#################################
# Create Button Click Calendar

 def callback():
    root2=Toplevel(f2)
    ttkcal = Calendar(root2,firstweekday=calendar.SUNDAY)
    ttkcal.pack(expand=1, fill='both')
    root2.update()
    root2.minsize(root2.winfo_reqwidth(), root2.winfo_reqheight())



 # Calendar Buttons

 b=ttk.Button(f2, width=4, text="Cal", command=callback).grid(column=3,row=1, sticky=W)

When I press the button, it opens the calendar window, but it is empty. And the console gives me error:

TypeError: __init__() got multiple values for argument 'firstweekday

Thank you

1 Answers1

1

Not so easy. The problem is that you mix the two GUI libraries. Therefore it is necessary two main event loops (at least): one for Tkinter code and one for PyQt code.
One way to do what you want - using subprocess and threading modules to run calendar.py in different thread. Example:

from tkinter import *
from tkinter import ttk

import subprocess
import threading

master = Tk()

def callback():
    subprocess.call('python calendar.py')


b=ttk.Button(master, width=4, text="Cal", command=lambda:threading.Thread(target=callback).start()).grid(column=3,row=1, sticky=W)


mainloop()

Another way - creating Qt main event loop inside callback function (dirty solution):

from tkinter import *
from tkinter import ttk
from calendar import Calendar
import sys
from PyQt4 import QtGui

master = Tk()

def callback():
    app = QtGui.QApplication(sys.argv)
    gui = Calendar()
    gui.show()
    app.exec_()


b=ttk.Button(master, width=4, text="Cal", command=callback).grid(column=3,row=1, sticky=W)

mainloop()

EDIT: How to call widget. First of all, look at this answer, and modify your ttkcalendar.py as kalgasnik suggested. Then try this:

from tkinter import *
from tkinter import ttk
from ttkcalendar import Calendar
import calendar

master = Tk()

def callback():
    root2=Toplevel(master)
    ttkcal = Calendar(root2,firstweekday=calendar.SUNDAY)
    ttkcal.pack(expand=1, fill='both')
    root2.update()
    root2.minsize(root2.winfo_reqwidth(), root2.winfo_reqheight())

b=ttk.Button(master, width=4, text="Cal", command=callback).grid(column=3,row=1, sticky=W)

mainloop()

EDIT 2. Solving the problems
Ok, it seems I found all problems.

  1. Actually, you import twice the same module - standard calendar module:

    from calendar import Calendar
    import calendar
    

But you do not import the class Calendar from ttkcalendar module (Do not forget to change it as described here). So, import should look like this:

import ttkcalendar
import calendar

Creating calendar (I changed the code a bit for clarity):

ttkcal = ttkcalendar.Calendar(root2,firstweekday=calendar.SUNDAY)
  1. In your code, the main window is initialized twice:
    line 15: master = Tk()
    line 960: root = Tk()
    You need to remove the first initialization.

  2. You mix pack() and grid() in the same master window. According the docs, it is a bad idea:

Warning: Never mix grid and pack in the same master window. Tkinter will happily spend the rest of your lifetime trying to negotiate a solution that both managers are happy with. Instead of waiting, kill the application, and take another look at your code. A common mistake is to use the wrong parent for some of the widgets.

So, instead nb.pack(fill='both', expand='yes') you have to write something like this nb.grid(column=0, row=0, sticky=(W, E))

Finally, here are links to the fixed code:

ttkcalendar.py (already modified, ready to use):
https://gist.github.com/anonymous/5e0d973f57e185572df2

Your script with described modifications:
https://gist.github.com/anonymous/65cb808dc64e414c0c12

Community
  • 1
  • 1
NorthCat
  • 9,643
  • 16
  • 47
  • 50
  • Thank you NorthCat. But I get this error no matter what option I use. (Clan or dirty) TclError: bad window path name ".123364520" – Alvaro Morales Solis Aug 26 '14 at 20:20
  • Or if what I do makes no sense, is there a calendar snipet for a calendar for Tkinter? – Alvaro Morales Solis Aug 26 '14 at 20:34
  • @AlvaroMoralesSolis There are several calendar sippets: 1) http://python-forum.org/viewtopic.php?f=12&t=5104#p6544 2) http://svn.python.org/projects/python/branches/pep-0384/Demo/tkinter/ttk/ttkcalendar.py 3) http://pythonical.sourceforge.net/dlgCalendar.py – NorthCat Aug 26 '14 at 21:01
  • Thank you, I am using this one: http://svn.python.org/projects/python/branches/pep-0384/Demo/tkinter/ttk/ttkcalendar.py For that snipet, what would be the best way to set the callback to display the widget after button click? Thank you – Alvaro Morales Solis Aug 29 '14 at 14:57
  • I don't even know how to update this. Does anybody know how to call the widget display at button press? – Alvaro Morales Solis Sep 04 '14 at 22:06
  • @AlvaroMoralesSolis I've updated the answer to include instructions on how to call a widget. – NorthCat Sep 05 '14 at 07:54
  • Thank you, I've tried that, but it is still giving me : TclError: bad window path name ".118974784" Any ideas why? – Alvaro Morales Solis Sep 11 '14 at 19:45
  • @AlvaroMoralesSolis When you receive an error? At the time of starting the program? – NorthCat Sep 12 '14 at 14:22
  • Yes, when I run it in Spyder. – Alvaro Morales Solis Sep 12 '14 at 14:58
  • I just found what the issue was. It is the master = Tk() on the code. The program has tabs. I use tab2 as f2 for the button. I removed the master = Tk() and the program now runs. However, the button is doing nothing when I press it. I updated my question so you can see what I have. Thank you – Alvaro Morales Solis Sep 12 '14 at 17:53
  • @AlvaroMoralesSolis `master = Tk()` creates the main window, so you can not do without it. Can you show your entire code? – NorthCat Sep 13 '14 at 13:06
  • Ok, the thing is that if I leave the master = Tk() it will give me the window path name error. The code is quite long. So I added it here: https://gist.github.com/anonymous/8e23c8e631a3908154bb In line 1088 you'll see the button. Thanks a lot for your patience and help! – Alvaro Morales Solis Sep 16 '14 at 14:24
  • @AlvaroMoralesSolis Can you give a link to your entire code? – NorthCat Sep 16 '14 at 14:27
  • Is the Gist one not working? gist.github.com/anonymous/8e23c8e631a3908154bb – Alvaro Morales Solis Sep 16 '14 at 17:33
  • @AlvaroMoralesSolis It seems, I corrected all the errors, and updated my answer. Try it! – NorthCat Sep 19 '14 at 06:14
  • Thank you! Sorry for the delay. Was out of the office. I will try it now. Just a question. If I install Python 3.4 and run this app with it, will I get problems since this app was created on 3.3.3? – Alvaro Morales Solis Oct 01 '14 at 17:02
  • @AlvaroMoralesSolis I checked my code on Python 3.3.0 and 3.4.1. It works well on both versions. So it should be no problem. – NorthCat Oct 01 '14 at 19:33
  • Awesome! It worked! You really helped me a lot. Thank you very much for your time and patience. For some reason I can't vote up your answer... It gives a -1. – Alvaro Morales Solis Oct 01 '14 at 20:10