I'm trying to make all tkinter
Entry
objects map Control-C to a copy event (and similar defaults for other commonly used shortcuts). This works for most Entry
objects, but fails in a strange way for a file dialog. A minimal example is below. I'm using Python 3.8.6 with Tkinter version 8.6.
import tkinter
from tkinter import filedialog
from tkinter import ttk
def ctrl_c_callback(event):
# I would like to do something like:
# event.widget.event_generate("<<Copy>>")
# but this results in the error
# AttributeError: 'str' object has no attribute 'event_generate'
# due to the fact 'event.widget' is a 'str' rather than a widget,
# as will now be demonstrated.
print(event.widget.__class__)
root = tkinter.Tk()
root.bind_class("TEntry", "<Control-c>", ctrl_c_callback)
save_button = ttk.Button(root, text="Save", command=filedialog.asksaveasfile)
save_button.grid()
root.deiconify()
root.mainloop()
Running this and clicking "Save" produces a dialog box, as expected. Now I select some text in the "File name" field near the bottom...
...and hit Control-C. I get:
<class 'str'>
I find this extremely surprising. Shouldn't event.widget
be a widget? Specifically, shouldn't it be an Entry
? Clearly, the event was triggered by an Entry
, because otherwise the Control-C binding should not have done anything.
If this is relevant, the value of the string is
.__tk_filedialog.contents.f2.ent
which seems like it might be the name of a widget in Tcl. (I do not know much about Tk in general.) As a last-ditch attempt, I tried using the root.nametowidget
method on this to see if I could get a widget, but this resulted in a KeyError
.
Note that, for other Entry
objects that I have manually created, I have no trouble getting the Control-C callback to copy the text as desired.