Я создаю текстовый редактор с указанием функции c, используя tkinter. Я хотел бы добавить возможность закладки и видел несколько примеров использования .yview () [0] или .index (INSERT) для получения номера первой строки yview или фактического номера строки, в которую должна быть добавлена закладка. , Что я не знаю, так это как настроить закладки на основе вставок / удалений строк в других частях текстового поля. Я использую отличный код, которым поделился Брайан Окли, для создания номеров строк для текстового поля. Этот код также предоставляет функцию «прокси», которая позволяет создавать виртуальные события для обработки различных функций tkinter (например, вставка, удаление, замена и т. Д. c). Вот код (слегка подправлен для обработки пробелов для другого шрифта) размеры):
class TextLineNumbers(tk.Canvas):
def __init__(self, *args, **kwargs):
tk.Canvas.__init__(self, *args, **kwargs)
self.textwidget = None
self.font_spacing = 0
self.setfontspacing(self.font_spacing)
def attach(self, text_widget):
self.textwidget = text_widget
def setfontspacing(self, spacing):
self.font_spacing = spacing
def redraw(self, *args):
'''redraw line numbers'''
self.delete("all")
i = self.textwidget.index("@0,0")
while True :
dline= self.textwidget.dlineinfo(i)
if dline is None: break
y = dline[1] + self.font_spacing
linenum = str(i).split(".")[0].zfill(7)
self.create_text(2,y,anchor="nw", text=linenum)
i = self.textwidget.index("%s+1line" % i)
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=None
try:
result = self.tk.call(cmd)
except Exception:
pass
# generate an event if something was added or deleted,
# or the cursor position changed
# print(cmd, args, "=>", result)
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")
if (args[0] in ("insert", "replace", "delete") ):
self.event_generate("<<Text_Change>>", when="now")
# return what the actual widget returned
return result
Я связал событие Text_Change с моим пользовательским текстовым виджетом, и это позволяет мне отслеживать изменения (т. е. увидеть, произошли ли изменения и запросить сохранение при выходе, et c.). Так что эта часть работает нормально.
Однако я не знаю, как получить информацию о строках, которые были вставлены / удалены при возникновении этих событий. Печать (cmd, args, "=>", result) дает много деталей, и я думаю, я мог бы найти способ вычислить дельты на основе этой информации, но это кажется сложным решением.
Мне было интересно, если бы кто-нибудь решал эту проблему раньше и может иметь предложения. Или, может быть, есть гораздо более простое решение, которое я пропускаю.
Спасибо