Text – многострочное текстовое поле
В этом уроке рассмотрим, как с помощью Tkinter запрограммировать такой элемент интерфейса как многострочное текстовое поле. Этот виджет часто встречается при заполнении веб-форм. В приложениях для десктопов он редок, если не считать программы «Терминал», где по-сути вы работаете в большом текстовом поле.
В tkinter многострочное текстовое поле создается от класса Text . По умолчанию его размер равен 80-ти знакоместам по горизонтали и 24-м по вертикали.
Однако эти свойства можно изменять с помощью опций width и height . Есть возможность конфигурировать шрифт, цвета и другое.
from tkinter import * root = Tk() text = Text(width=25, height=5, bg="darkgreen", fg='white', wrap=WORD) text.pack() root.mainloop()
Значение WORD опции wrap позволяет переносить слова на новую строку целиком, а не по буквам.
Text и Scrollbar
Если в текстовое поле вводится больше линий текста, чем его высота, то оно само будет прокручиваться вниз. При просмотре прокручивать вверх-вниз можно с помощью колеса мыши и стрелками на клавиатуре. Однако бывает удобнее пользоваться скроллером – полосой прокрутки. Кроме того его появление, или когда он становится активным, делает очевидным, что контент превышает размеры поля.
В tkinter скроллеры производятся от класса Scrollbar . Объект-скроллер связывают с виджетом, которому он требуется. Это не обязательно многострочное текстовое поле. Часто полосы прокрутки бывают нужны спискам, которые будут рассмотрены позже.
from tkinter import * root = Tk() text = Text(width=20, height=7) text.pack(side=LEFT) scroll = Scrollbar(command=text.yview) scroll.pack(side=LEFT, fill=Y) text.config(yscrollcommand=scroll.set) root.mainloop()
Здесь создается скроллер, к которому с помощью опции command привязывается прокрутка текстового поля по оси y – text.yview . В свою очередь текстовому полю опцией yscrollcommand устанавливается ранее созданный скроллер – scroll.set .
Методы Text
Основные методы у Text такие же как у Entry – это get , insert , delete . Однако, если в случае однострочного текстового поля было достаточно указать один индекс позиции при вставке или удалении, то в случае многострочного надо указывать два – номер строки и номер символа в этой строке (другими словами, номер столбца). При этом нумерация строк начинается с единицы, а столбцов – с нуля.
from tkinter import * def insert_text(): s = "Hello World" text.insert(1.0, s) def get_text(): s = text.get(1.0, END) label['text'] = s def delete_text(): text.delete(1.0, END) root = Tk() text = Text(width=25, height=5) text.pack() frame = Frame() frame.pack() Button(frame, text="Вставить", command=insert_text).pack(side=LEFT) Button(frame, text="Взять", command=get_text).pack(side=LEFT) Button(frame, text="Удалить", command=delete_text).pack(side=LEFT) label = Label() label.pack() root.mainloop()
Методы get и delete могут принимать не два, а один аргумент. В таком случае будет обрабатываться только один символ в указанной позиции.
Теги
Особенностью текстового поля библиотеки Tk является возможность форматировать текст в нем, то есть придавать его разным частям разное оформление. Делается это с помощью методов tag_add и tag_config . Первый добавляет тег, при этом надо указать его произвольное имя и отрезок текста, к которому он будет применяться. Метод tag_config настраивает тегу стили оформления.
from tkinter import * root = Tk() text = Text(width=50, height=10) text.pack() text.insert(1.0, "Hello world!\nline two") text.tag_add('title', 1.0, '1.end') text.tag_config('title', justify=CENTER, font=("Verdana", 24, 'bold')) root.mainloop()
Вставка виджетов в текстовое поле
В Text можно вставлять другие виджеты помощью метода window_creat . Потребность в этом не велика, однако может быть интересна с объектами типа Canvas . Данный класс будет изучен позже. В примере ниже вставляется метка в текущую ( INSERT ) позицию курсора.
from tkinter import * def smile(): label = Label(text=":)", bg="yellow") text.window_create(INSERT, window=label) root = Tk() text = Text(width=50, height=10) text.pack() button = Button(text=":)", command=smile) button.pack() root.mainloop()
Определение метки в теле функции позволяет каждый раз при вызове последней создавать новую метку. Иначе, если бы метка была в основной ветке программы, предыдущая исчезала бы.
Практическая работа
Напишите программу, состоящую из однострочного и многострочного текстовых полей и двух кнопок «Открыть» и «Сохранить». При клике на первую должен открываться на чтение файл, чье имя указано в поле класса Entry , а содержимое файла должно загружаться в поле типа Text .
При клике на вторую кнопку текст, введенный пользователем в экземпляр Text , должен сохраняться в файле под именем, которое пользователь указал в однострочном текстовом поле.
Файлы будут читаться и записываться в том же каталоге, что и файл скрипта, если указывать имена файлов без адреса.
Для выполнения практической работы вам понадобится функция open языка Python и методы файловых объектов чтения и записи. Освежить знания о них можно здесь.
Курс с примерами решений практических работ: pdf-версия
Tkinter. Программирование GUI на Python
Python tkinter text tags
Теги позволяют определить форматирование. Тег добавляется с помощью метода add_tag() класса Text:
tag_add(tagName, index1, index2)
Первый параметр устанавливает имя тега, второй параметр — index1 указывает на начальный символ, с которого начинает применяться тег. Дополнительно (но необязательно) можно указать третий параметр, который устанавливает конечный символ, к которому применяется тег.
Для прикрепления тега к определенному тексту также можно использовать метод insert, который добавляет текст, и в качестве второго параметра передать тег или набор тегов, которые будут применяться к добавляемому тексту:
insert(index, text, tagName) insert(index, text, (tagName1, tagName2. tagNameN))
С помощью метода tag_configure() для тега можно сконфигурировать стили.
tag_configure(имя_тега, стили)
Стили представляют параметры background, bgstipple, borderwidth, elide, fgstipple, font, foreground, justify, lmargin1, lmargin2, offset, overstrike, relief, rmargin, spacing1, spacing2, spacing3, tabs, tabstyle, underline и wrap, которым передаются некоторые значения.
from tkinter import * root = Tk() root.title("METANIT.COM") root.geometry("250x200") editor = Text(wrap = "none") editor.pack(expand=1, fill=BOTH) editor.insert("1.0","Hello ") # создаем тег highlightline и прикрепляем его к символам 1.0 до 1.2 editor.tag_add("highlightline", "1.0", "1.2") # добавляем текст, к которому применяется тег highlightline editor.insert("end","World", "highlightline") editor.insert("end","\nHello All!") # устанавливаем стили тега highlightline editor.tag_configure("highlightline", background="#ccc", foreground="red", font="TkFixedFont", relief="raised") root.mainloop()
Здесь создается тег «highlightline», который прикрепляется сначала по 2-й символ в первой строке. Далее добавляется текст «World», к которму применяется данный тег. В конце конфигурируем тег, задавая его стилевые параметры:
Если в процессе работы программы тег стал не нужен, его можно удалить. Метод remove_tag() удаляет тег с определенных символов:
editor.tag_remove("highlightline", "1.0", "1.2")
В данном случае удаляем тег «highlightline» с символов с 0 по 2-й в первой строке.
Также можно вообще удалить тег со всех символов, к которым он применяется:
editor.tag_delete("highlightline")
Добавление изображений и других виджетов
Виджет Text позволяет добавление изображений и других виджетов.
Для добавления изображений применяется метод image_create :
from tkinter import * root = Tk() root.title("METANIT.COM") root.geometry("250x200") editor = Text() editor.pack(expand=1, fill=BOTH) python_img = PhotoImage(file="python_sm.png") editor.image_create("1.0", image=python_img) root.mainloop()
В метод image_create в качестве первого параметра передается позиция вставки изображения. В качестве второго параметра — image указывается файл изображения:
Аналогично можно добавлять другие виджеты в Text с помощью метода window_create()
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") editor = Text() editor.pack(expand=1, fill=BOTH) def click(): editor.insert("2.0", "Click\n") btn = ttk.Button(editor, text="Click", command=click) editor.window_create("1.0", window=btn) root.mainloop()
Первый параметр метода window_create также позиция создания виджета, а второй параметр — window указывает на добавляемый виджет, в данном случае это кнопка, на которую также можно нажимать и также можно обрабатывать ее нажатия