Работа с интерфейсом / подсказка к 4 задачке

4

Написать программу с помощью которой можно открыть текстовый файл и показать его содержимое.

Снова начнем с болванки кода, сделаем интерфейс чуть побольше

from tkinter import *


def my_setup(gui):
    gui.geometry("600x400")
 

gui = Tk()
my_setup(gui)
gui.mainloop()

тут мы попробуем сразу две вещи

  1. Использование компоненты для работы с многострочным текстом
  2. Чтение данных из файла

Для многострочного текста используется компонента Text, добавляется она очень просто:

def my_setup(gui):
    gui.geometry("600x400")
		
    text = Text(gui) # создали компоненту в памяти
    text.place(x=0, y=0, width=600, height=350) # поставили ее на форму

я установил ширину компоненты равной ширине формы, а высоту сделал чуть меньше, чтобы потом можно было добавить кнопочки какие-нибудь, получится так:

то есть вполне рабочая компонента, можно вставлять, писать, удалять текст. В общем по сути обыкновенный блокнот.

Создаем проект в Spyder

Давайте теперь настроим наш редактор Spyder так чтобы удобнее было работать с проектом. Так как я хочу читать файлик, а также чего-нибудь писать в него. Было бы удобно работать не с отдельным файлом, а с целой папкой. Делается это так:

Выбираем в меню

затем

жмем create

он скорее всего немного подумает, а затем слева откроется новая панелька с содержимым папки

тычем на имя папки и создаем новый файл

откроется новосозданный файлик

и теперь просто скопируем в него содержимое, нашего старого файлика

from tkinter import *


def my_setup(gui):
    gui.geometry("600x400")
    text = Text(gui)
    text.place(x=0, y=0, width=600, height=350)
 

gui = Tk()
my_setup(gui)
gui.mainloop()

Создаем файл с текстом

Давайте теперь создадим еще один файлик, но просто текстовый:

я назову его text.txt

И загоним в него какой-нибудь текст

Червонные Король и Королева сидели на троне, а вокруг толпились остальные карты и множество всяких птиц и зверюшек. Перед троном стоял между двумя солдатами Валет в цепях. Возле Короля вертелся Белый Кролик - в одной руке он держал трубу, а в другой - длинный пергаментный свиток. Посередине стоял стол, а на столе - большое блюдо с кренделями. Вид у них был такой аппетитный, что у Алисы прямо слюнки потекли.

- Скорее бы кончили судить, - подумала она, - и подали угощение.

Особых надежд на это, однако, не было, и она начала смотреть по сторонам, чтобы как-то скоротать время.

Раньше Алиса никогда не бывала в суде, хотя и читала о нем в книжках. Ей было очень приятно, что все почти здесь ей знакомо.

- Вон судья, - сказала она про себя. - Раз в парике, значит судья.

Судьей, кстати, был сам Король, а так как корону ему пришлось надеть на парик, он чувствовал себя не слишком уверенно. К тому же это было не очень красиво.

и так подготовительные действия окончены

Добавляем кнопку на форму

Теперь давайте добавим кнопку с помощью которой можно будет прочитать содержимое файла и вывести его в наш Text.

Добавляем кнопку:

def my_setup(gui):
    gui.geometry("600x400")
    text = Text(gui)
    text.place(x=0, y=0, width=600, height=350)
    
    button = Button(gui, text="Прочитать файл")
    button.place(x=10, y=360)

вот так получается:

она правда пока не работает.

Добавляем ей команду:

def my_setup(gui):
    gui.geometry("600x400")
    text = Text(gui)
    text.place(x=0, y=0, width=600, height=350)
    
    def button_click():
        print("Тыкнул")
    
    button = Button(gui, text="Прочитать файл", command=button_click)
    button.place(x=10, y=360)

проверяем:

кнопка реагирует! =)

Теперь пропишем код с помощью которого можно прочитать содержимое файла, выглядит он немного хитро, пишем внутрь button_click:

def button_click():
    with open("text.txt") as f: # эта страшная строчка означает открой файл text.txt и подключи файл к переменной f
        print(f.read()) # f.read() -- значит прочитай содержимое файла и верни в качестве строки, ну а print это чтобы напечатать

проверяем:

ну, э… что-то на текст похожее вывел, но вот что именно не понятно… такое себе в общем

Кстати если у вас вывелось все ок, то можете пропустить следующий пункт

Чиним кодировку

На самом деле тут проблема в кодировке (в компьютере текст хранится в виде чисел, а кодировка определяет какому числу какую букву сопоставить). В windows стандартной считается кодировка cp1251, и питон именно ее и ожидает. В то же время все современные инструменты для программирования хранят текст в кодировке UTF8. Если открыть любой файл, то вот ее видно внизу будет:

поэтому чтобы символы приобрели смысл надо явно указать, что мы ожидаем, что в файле находится utf8 кодировка, делается это вот так:

def button_click():
    with open("text.txt", encoding="utf8") as f:
        print(f.read())

запускаем:

от теперь другое дело!)

Выводим содержимое файла на форму

Как я выше говорил, f.read() возвращает содержимое файла в виде строки, мы можем его спокойно загнать в переменную и потом вывести ее на форму, вот так:

def button_click():
    with open("text.txt", encoding="utf8") as f: # открыл файл
        content = f.read() # сохранил его содержимое в переменную content
    
    text.insert("1.0", content) # вставил в компоненту текст

и сразу очевидный вопрос, что за 1.0?

Короче так как вставлять текст в многострочную компоненту это вам не работа с одной строкой, то и механизм немного сложнее. Вставляя текст надо указывать две координаты, номер строки и номер символа в строке.

Таким образом 1 – означает первую строку (причем нумерация идет с 1 для строк), 0 – означает нулевой символ в строке (тут нумерация с 0). Так как у нас текст на форме изначально отсутствует то на самом деле большого значения что указывать в качестве координаты значения не имеет.

В общем проверяем:

ура задание готово! =)