Reputation:
I am working on a text editor using tkinter in python 3. I am having an issue with the custom text field class that I am using to attatch line numbers. It is from the answer from Brian Oakley to this question. Here is the code for the class:
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
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, *args):
# let the actual widget perform the requested action
cmd = (self._orig,) + args
result = self.tk.call(cmd)
# generate an event if something was added or deleted,
# or the cursor position changed
if (args[0] in ("insert", "replace", "delete") or
args[0:3] == ("mark", "set", "insert") or
args[0:2] == ("xview", "moveto") or
args[0:2] == ("xview", "scroll") or
args[0:2] == ("yview", "moveto") or
args[0:2] == ("yview", "scroll")
):
self.event_generate("<<Change>>", when = "tail")
# return what the actual widget returned
return result
Here is the code for the cut function:
def cutSelected(event=None):
textField.event_generate("<<Cut>>")
...
# Add cut to the edit menu in the menu bar
editMenu.add_command(label = "Cut", command = cutSelected, accelerator = "Ctrl+X")
...
# setting up the keyboard shortcut for the cut function
textField.bind("<Control-x>", cutSelected)
textField.bind("<Control-X>", cutSelected)
Here is the code for the paste function:
def paste(event=None):
textField.event_generate("<<Paste>>")
...
# Add paste to the edit menu in the menu bar
editMenu.add_command(label = "Paste", command = paste, accelerator = "Ctrl+V")
...
# setting up the keyboard shortcut for the paste function
textField.bind("<Control-v>", paste)
textField.bind("<Control-V>", paste)
Here is the error traceback (except for the credentials from the paths):
Traceback (most recent call last):
File "C:\Users\me\mydocuments\Programming\myeditor\main.py", line 457, in <module>
root.mainloop()
File "C:\Users\me\AppData\Local\Programs\Python\Python37-
32\lib\tkinter\__init__.py", line 1283, in mainloop
self.tk.mainloop(n)
File "C:\Users\me\mydocuments\Programming\myeditor\main.py", line 58, in _proxy
result = self.tk.call(cmd)
_tkinter.TclError: text doesn't contain any characters tagged with "sel"
When I try to paste the text via the keyboard shortcut, it doesn't give me an error, it just pastes my text twice on the same line. (ex: test
gets pasted as testtest
) but when I do it via the edit menu in the menu bar, I get the error shown above.
Cut works just fine when I do it from the edit menu but when I try to cut text via the keyboard shortcut, I get the error.
I have been trying to fix these issues for almost a week now and the closest that I have come to an answer was from this question on stack overrun. I tried that code and had the exact same problem. I am not sure what else to do so any help at all is greatly appreciated.
Upvotes: 1
Views: 701
Reputation: 385970
_tkinter.TclError: text doesn't contain any characters tagged with "sel"
I don't think I have a proper fix, but I have something that prevents your code from crashing.
Replace this:
result = self.tk.call(cmd)
... with this:
try:
result = self.tk.call(cmd)
except Exception:
return None
It may mask other things that should legitimately throw an error, but at the moment it's the best solution I have.
When I try to paste the text via the keyboard shortcut, it doesn't give me an error, it just pastes my text twice on the same line.
It's probably doing it twice because tkinter already has a default binding for cut and paste. What's probably happening is that your binding is firing and then the built-in binding is firing. If you want to prevent the built-in binding from taking effect you need to return "break"
from paste
. I'm only guessing at this point since you didn't provide a [mcve] for that.
Upvotes: 2