Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tkinter et menu contextuel copier-coller et couper

    26 février 2024 à 11:27:55

    Salut,

    Tkinter ne possédant pas de menu contextuel pour les actions "copier/coller et couper", j'ai créé une petite classe à partir de différents exemples trouvés sur le net.

    Merci vos retours et améliorations.

    Code :

    import tkinter as tk
    import platform
    
    
    class ContextMenuWidget(tk.Menu):
        """Extended widget with a context menu that includes Cut, Copy, and Paste commands."""
    
        def __init__(self, widget: tk.Widget, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
            self.widget = widget
            self.config(tearoff=False)
    
            self.add_command(label="Couper", accelerator="Ctrl+X", command=self.popup_cut)
            self.add_command(label="Copier", accelerator="Ctrl+C", command=self.popup_copy)
            self.add_command(label="Coller", accelerator="Ctrl+V", command=self.popup_paste)
            self.add_separator()
            self.add_command(label="Tout sélectionner", accelerator="Ctrl+A", command=self.select_all)
    
            self.map_right_button_event()
    
            self.widget.bind("<<RightClick>>", self.show_menu)
            self.widget.bind("<Control-a>", self.select_all)
            self.widget.bind("<Control-A>", self.select_all)
    
        def map_right_button_event(self):
            if platform.system() == "Darwin":
                self.event_add("<<RightClick>>", "<Button-2>")
            else:
                self.event_add("<<RightClick>>", "<Button-3>")
    
        def update_menu_state(self):
            if isinstance(self.widget, tk.Text):
                widget_content = self.widget.get("1.0", tk.END).strip()
            else:
                try:
                    widget_content = self.widget.get()
                except AttributeError as error:
                    print(error)
                    return False
    
            clipboard_content = self.widget.clipboard_get()
            content_available = bool(widget_content)
    
            self.entryconfig("Couper", state="normal" if content_available else "disabled")
            self.entryconfig("Copier", state="normal" if content_available else "disabled")
            self.entryconfig("Coller", state="normal" if clipboard_content else "disabled")
            self.entryconfig("Tout sélectionner", state="normal" if content_available else "disabled")
    
            return True
    
        def popup_cut(self):
            self.widget.event_generate("<<Cut>>")
    
        def popup_copy(self):
            self.widget.event_generate("<<Copy>>")
    
        def popup_paste(self):
            self.widget.event_generate("<<Paste>>")
    
        def show_menu(self, event=None):
            if self.update_menu_state():
                self.tk_popup(event.x_root, event.y_root)
    
        def select_all(self, event=None):
            self.widget.event_generate("<<SelectAll>>")
            return "break"
    
    
    root = tk.Tk()
    
    label_entry = tk.Label(root, text="Entry Widget : ")
    label_entry.grid(column=0, row=0, sticky="w")
    
    widget_entry = tk.Entry(root, width=31)
    widget_entry.grid(column=1, row=0, sticky="w")
    ContextMenuWidget(widget_entry)
    
    label_text = tk.Label(root, text="Text Widget : ")
    label_text.grid(column=0, row=1, sticky="wn")
    
    widget_text = tk.Text(root, height=13, width=31, wrap=tk.NONE)
    widget_text.grid(column=1, row=1, sticky="w")
    ContextMenuWidget(widget_text)
    
    vertical_scrollbar = tk.Scrollbar(root, orient=tk.VERTICAL)
    vertical_scrollbar.grid(column=2, row=1, sticky="ns")
    widget_text.config(yscrollcommand=vertical_scrollbar.set)
    vertical_scrollbar.config(command=widget_text.yview)
    
    horizontal_scrollbar = tk.Scrollbar(root, orient=tk.HORIZONTAL)
    horizontal_scrollbar.grid(column=1, row=2, sticky="we")
    widget_text.config(xscrollcommand=horizontal_scrollbar.set)
    horizontal_scrollbar.config(command=widget_text.xview)
    
    root.mainloop()



    -
    Edité par Garkam 26 février 2024 à 17:51:15

    • Partager sur Facebook
    • Partager sur Twitter

    Tkinter et menu contextuel copier-coller et couper

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    • Editeur
    • Markdown