Osprey
Osprey

Reputation: 21

Why am I getting invalid command name ".!canvas"? I couldn't find a working solution anywhere

I am working on a project that automates your virtual school schedule by automatically joining your meetings on time and alerting you about them. What I am trying to have right now is a working tkinter setup window in which you can add links to a dictionary variable. All I want is for a window that asks the user to enter a link and a number and for the user to be able to click a "Finish" button that will destroy the window. I got the code down, hopefully, but I keep getting "in _create return self.tk.getint(self.tk.call( _tkinter.TclError: invalid command name ".!canvas"". I've done a good amount of research and I can't find a solution. Note: I've already tried win.update() and moving the win.mainloop() to the bottom.

# Import Webbrowser
import webbrowser as wb

# Import Tkinter
import tkinter as tk

# Set Up Tkinter Window
win = tk.Tk()
win.title("Setup")
win.resizable(False, False)

# Set Up Tkinter Canvas
canvas = tk.Canvas(win, width=400, height=300)
canvas.pack()

# Set Up Tkinter Big Header
header = tk.Label(win, text="Auto School Meetings Setup")
header.config(font=("helvetica", 14))
canvas.create_window(200, 25, window=header)

# Set Up Tkinter Entry
instructions = tk.Label(win, text="Enter a link and time here for every class you have")
instructions.config(font=("helvetica", 10))
canvas.create_window(200, 100, window=instructions)

linkEntry = tk.Entry(win)
canvas.create_window(200, 140, window=linkEntry)

timeEntry = tk.Entry(win)
canvas.create_window(200, 180, window=timeEntry)

# Create Link Dictionary From Input
finished = False
links = {}


def addLink(t, newLink):
    links[t] = newLink

link = linkEntry.get()
time = timeEntry.get()
addBtn = tk.Button(
    text="Add Link",
    command=addLink(time, link),
    bg="blue",
    fg="white",
    font=("helvetica", 9, "bold"),
)
canvas.create_window(100, 220, window=addBtn)
quitBtn = tk.Button(
    text="Finish Setup",
    command=win.destroy(),
    bg="green",
    fg="white",
    font=("helvetica", 9, "bold"),
)
canvas.create_window(300, 220, window=quitBtn)
win.update()
win.mainloop()

# Test Links
wb.open(links.get("1", "www.google.com"))

Heres the exact error:

Traceback (most recent call last):
  File "c:\Users\Osprey\Desktop\School Meetings\main.py", line 58, in <module>
    canvas.create_window(300, 220, window=quitBtn)
  File "C:\Users\Osprey\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 2809, in create_window
    return self._create('window', args, kw)
  File "C:\Users\Osprey\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 2771, in _create
    return self.tk.getint(self.tk.call(
_tkinter.TclError: invalid command name ".!canvas"

Upvotes: 1

Views: 236

Answers (1)

Barmar
Barmar

Reputation: 781028

TL;DR: Remove the parentheses after win.destroy(). It should be win.destroy.

You're not using the command option to the Tk.Button function correctly. The argument needs to be a function reference, so that the function can be called when the button is clicked. You're calling the function when you create the button, instead of passing a reference.

If you want to pass parameters, use a lambda, as I've shown below in addBtn.

If there are no parameters, just pass the function name, without putting () after it.

addBtn = tk.Button(
    text="Add Link",
    command=lambda: addLink(time, link),
    bg="blue",
    fg="white",
    font=("helvetica", 9, "bold"),
)
canvas.create_window(100, 220, window=addBtn)
quitBtn = tk.Button(
    text="Finish Setup",
    command=win.destroy,
    bg="green",
    fg="white",
    font=("helvetica", 9, "bold"),
)

Upvotes: 2

Related Questions