Search code examples
python-3.xtkintertkinter-entry

Why is selection_clear() in Entry of tkinter invalid?


I want to realize "Cut" in Rightkey menu by the following code:

self.entry_title = entry(frm, RIGHT, self.title, width = 58)
def menubarCut(self):
    if not self.entry_title.selection_present():
        showerror('***', 'No text selected')
    else:
        text = self.entry_title.selection_get()
        self.entry_title.selection_clear()
        self.clipboard_clear()
        self.clipboard_append(text)

However, menubarCut returns the effect of "Copy" instead of "Cut". Namely, the results returned by the above code is the same as that returned by the following code:

self.entry_title = entry(frm, RIGHT, self.title, width = 58)
def menubarCopy(self):
    if not self.entry_title.selection_present():
        showerror('***', 'No text selected')
    else:
        text = self.entry_title.selection_get()
        self.clipboard_clear()
        self.clipboard_append(text)

It seems that self.entry_title.selection_clear() has no effect. Why does that happen? How can I solve this problem?


Solution

  • Based on @BryanOakley's answer to tkinter copy-pasting to Entry doesn't remove selected text, I would guess this is what you want:

    def menubarCut(self):
        if self.entry_title.selection_present():
            text = self.entry_title.selection_get()
            self.entry_title.delete("sel.first", "sel.last")
            self.clipboard_clear()
            self.clipboard_append(text)
        else:
            showerror('***', 'No text selected')
    

    The selection_clear() method clears the act of selection (the highlighting) not the actual text that's selected. FYI, here's the MCVE I created to test this:

    import sys
    import tkinter as tk
    
    class Application(tk.Frame):
    
        def __init__(self, master=None):
            super().__init__(master)
    
            self.entry_title = tk.Entry(master, width=50)
            self.entry_title.pack()
    
            self.entry_title.bind('<Escape>', self.event_handler)
    
        def menubarCut(self):
            if self.entry_title.selection_present():
                text = self.entry_title.selection_get()
                self.entry_title.delete("sel.first", "sel.last")
                self.clipboard_clear()
                self.clipboard_append(text)
            else:
                print('No text selected', file=sys.stdderr)
    
        def event_handler(self, event):
            self.menubarCut()
    
    root = tk.Tk()
    Application(root)
    root.mainloop()