Нумерация строк, tkinter
я пытаюсь сделать нумерацию строк в текстовом редакторе. Я нашёл код на нумерацию строк от Брайана Окли и я попробовал его задействовать в своем коде. Вот тут я запутался, теперь я не понимаю как сделать чтобы нумерация строк была в одном текстовом поле. Вот код:
from tkinter import *
from tkinter import filedialog, ttk
import tkinter as tk
from lines import TextLineNumbers, CustomText, Example
import os
title = 'Notepad'
root = Tk()
root.geometry('800x600')
root.title(title)
tabs = {'ky': 0}
tab_list = []
# Example(root).pack(side="top", fill="both", expand=True)
notebook = ttk.Notebook(root)
# --------------------
def open_file():
textWidget = Text(root)
file = open(filedialog.askopenfilename(), 'r')
title = os.path.basename(file.name)
tab = add_tab(title)
root.title(title + " - Notepad")
data = file.read()
tab.textWidget.delete(1.0, "end")
tab.textWidget.insert(1.0, data)
file.close()
def add_tab(name):
notebook.pack(expand=True, fill='both')
tab = Tab(notebook, name)
print(name)
notebook.add(tab, text=name)
tab_list.append(tab)
return tab
def save_file():
tab_to_save = get_tab()
print(tab_to_save)
tab_to_save.save_tab()
def get_tab():
print(notebook.index('current'))
#Get the tab object from the tab_list based on the index of the currently selected tab
tab = tab_list[notebook.index('current')]
return tab
def generate_tab():
if tabs['ky'] < 20:
tabs['ky'] += 1
add_tab('Document ' + str(tabs['ky']))
def run():
root.mainloop()
# --------------------
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="New...", command= generate_tab)
filemenu.add_command(label="Open", command = open_file)
filemenu.add_command(label="Save", command= save_file)
filemenu.add_separator()
filemenu.add_command(label="Exit", command= root.quit)
menubar.add_cascade(label="File", menu = filemenu)
editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Undo")
editmenu.add_command(label="Redo")
menubar.add_cascade(label="Edit", menu=editmenu)
root.config(menu=menubar)
class Tab(Frame):
def __init__(self, root, name):
Frame.__init__(self, root)
self.root = root
self.name = name
self.textWidget = Text(self, font = "DejaVuSansMono 10", fg = "#111")
self.textWidget["bg"] = "#fff"
self.textWidget.pack(fill='both', expand=True)
def save_tab(self):
print(self.textWidget.get("1.0", 'end-1c'))
file = open(filedialog.asksaveasfilename() + '.txt', 'w+')
file.write(self.textWidget.get("1.0", 'end-1c'))
print(os.path.basename(file.name))
#title = os.path.basename(file.name)
file.close()
# --------------------
if __name__ == '__main__':
print("done!")
run()

Ответы (1 шт):
Автор решения: insolor
→ Ссылка
Нужно создавать CustomText внутри вашего таба вместо Text, там же привязывать панель с номерами строк, и добавить скроллбар, все по аналогии с кодом из класса Example:
class Tab(Frame):
def __init__(self, root, name):
Frame.__init__(self, root)
self.root = root
self.name = name
# Текстовое поле
self.textWidget = CustomText(self, font = "DejaVuSansMono 10", fg = "#111", bg = "#fff")
# Панель с номерами строк
linenumbers = TextLineNumbers(self, width=30)
linenumbers.attach(self.textWidget)
# Перерисовка панели с номерами при изменениях в текстовом виджете
def on_change(event):
linenumbers.redraw()
self.textWidget.bind("<<Change>>", on_change)
self.textWidget.bind("<Configure>", on_change)
# Вертикальная полоса прокрутки
vsb = tk.Scrollbar(self, orient="vertical", command=self.textWidget.yview)
self.textWidget.configure(yscrollcommand=vsb.set)
# Размещаем панель номеров слева, полосу прокрутки справа,
# потом уже текстовое поле на оставшемся месте между ними
linenumbers.pack(side="left", fill="y")
vsb.pack(side="right", fill="y")
self.textWidget.pack(fill='both', expand=True)
Сравните с классом Example из ответа:
class Example(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.text = CustomText(self)
self.vsb = tk.Scrollbar(orient="vertical", command=self.text.yview)
self.text.configure(yscrollcommand=self.vsb.set)
self.text.tag_configure("bigfont", font=("Helvetica", "24", "bold"))
self.linenumbers = TextLineNumbers(self, width=30)
self.linenumbers.attach(self.text)
self.vsb.pack(side="right", fill="y")
self.linenumbers.pack(side="left", fill="y")
self.text.pack(side="right", fill="both", expand=True)
self.text.bind("<<Change>>", self._on_change)
self.text.bind("<Configure>", self._on_change)
...
def _on_change(self, event):
self.linenumbers.redraw()
Все примерно то же самое, только я не стал делать панель номеров и сколлбар полями объекта Tab, и немного по-другому организовал код.
