Search code examples
pythontkintereventscopy-paste

why can i not use ctrl + v with a virtual event tkinter text widget python


i use a tkinter text widget and i have copied the script in this answer to bind a event for every change the text widget.

the code for the text widget:

"""I found this script here: https://stackoverflow.com/questions/40617515/python-tkinter-text-modified-callback"""
import tkinter as tk


class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        """A text widget that report on internal widget commands"""
        tk.Text.__init__(self, *args, **kwargs)

        # create a proxy for the underlying widget
        self._orig = self._w + "_orig"
        self.tk.call("rename", self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)

    def _proxy(self, command, *args):
        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)

        if command in ("insert", "delete", "replace"):
            self.event_generate("<<TextModified>>")

        return result

now the problem is that when a paste some text in the text widget i get this error:

Traceback (most recent call last):
  File "C:\Users\Gebruiker\PycharmProjects\mylanguage\main.py", line 91, in <module>
    app.mainloop()
  File "C:\Users\Gebruiker\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1429, in mainloop
    self.tk.mainloop(n)
  File "C:\Users\Gebruiker\PycharmProjects\mylanguage\customtext.py", line 17, in _proxy
    result = self.tk.call(cmd)
_tkinter.TclError: text doesn't contain any characters tagged with "sel"

Process finished with exit code 1

so i want i can paste some text without getting this error. can someone help?


Solution

  • _tkinter.TclError: text doesn't contain any characters tagged with "sel"
    

    You are getting an error when you do either delete or copy. To solve problem. just add two tags one for get and one for delete.

    Snippet code:

    def _proxy(self, command, *args):
        # avoid error when copying
        if command == 'get' and (args[0] == 'sel.first' and args[1] == 'sel.last'): return
    
        # avoid error when deleting
        if command == 'delete' and (args[0] == 'sel.first' and args[1] == 'sel.last'): return
    
        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)
    
        if command in ('insert', 'delete', 'replace'):
                    self.event_generate('<<TextModified>>')
    
        return result
    

    Screenshot before:

    enter image description here

    Screenshot after ctrl+v:

    enter image description here