Событие выделения текста в TKinter
Я пишу GUI с использованием TKinter. И столкнулся с проблемой, на которую я не нашел решения:
В моём интерфейсе есть поле для ввода (Entry). Пользователь вводит в него некую информацию. Мне нужно что-бы пользователь не мог выделить текст в этом поле. Это важно.
Я пробовал решить эту проблему тем, что создавал поток с помощью Threading, и в бесконечном цикле очищал выделение с помощью selection_clear(). Но сомневаюсь что это хорошее решение. Может есть способ отслеживать событие выделения текста в Entry?
Ответы (1 шт):
Не знаю есть ли нативный способ сделать это кодом на Питоне... Но т.к. в tkinter доступен интерпретатор Tcl/Tk, то через Tcl можно перехватить (переопределить) процедуру работы с созданным виджетом (в Tcl каждый виджет создаёт собственную команду (имеющую такое же имя как и сам виджет) для управления собой). А в этой процедуре просто ничего не делать, если её вызвали с параметрами selection range (установка выделения), а для остальных вариантов вызова передавать управление старой процедуре. Эта блокировка будет работать даже с дефолтными биндингами, т.к. они тоже работают с виджетом через использование этой процедуры.
import tkinter as tk
from tkinter import ttk
def set_entry_no_select(root, entry):
root.eval(f"""
rename {entry} {entry}_orig
proc {entry} args {{
if {{[string match {{se*}} [lindex $args 0]] &&
[string match {{[atr]*}} [lindex $args 1]]}} {{
# disable "selection adjust|to|range" sub-commands
return
}}
tailcall {entry}_orig {{*}}$args
}}
""")
root = tk.Tk()
text = tk.StringVar(root, "Entry Entry Entry")
entry = tk.Entry(textvariable=text)
set_entry_no_select(root, entry)
entry.pack()
text2 = tk.StringVar(root, "TtkEntry TtkEntry TtkEntry")
entry2 = ttk.Entry(textvariable=text2)
set_entry_no_select(root, entry2)
entry2.pack()
root.mainloop()