We bind the right-click event to the show_popup handler for the text instance, which displays the menu with its top-left corner over the clicked position. Each time this event is triggered, the same menu instance is displayed again:
def show_popup(self, event):
self.menu.post(event.x_root, event.y_root)
The following methods are available for all widget classes to interact with the clipboard:
- clipboard_clear(): Clears the data from the clipboard
- clipboard_append(string): Appends a string to the clipboard
- clipboard_get(): Returns the data from the clipboard
The callback method for the copy action gets the current selection and adds it to the clipboard:
def copy_text(self):
selection = self.text.tag_ranges(tk.SEL)
if selection:
self.clipboard_clear()
self.clipboard_append(self.text.get(*selection))
The paste action inserts the clipboard contents into the insertion cursor position, defined by the INSERT index. We have to wrap this in a try...except block, since calling clipboard_get raises a TclError if the clipboard is empty:
def paste_text(self):
try:
self.text.insert(tk.INSERT, self.clipboard_get())
except tk.TclError:
pass
The delete action does not interact with the clipboard, but removes the contents of the current selection:
def delete_text(self):
selection = self.text.tag_ranges(tk.SEL)
if selection:
self.text.delete(*selection)
Since the cut action is a combination of copy and delete, we reused these methods to compose its callback function.