Рубрики
Без рубрики

Давайте создадим редактор разметки игрушек с Python Tkinter!

Редактор Markdown – одна из тенденций в наше время. Все создают редактор Markown, SOM … Теги с Python, начинающими, TKinter, Markdown.

Редактор Markdown – одна из тенденций в наше время. Все создают редактор Markown, некоторые из них являются инновационными, но некоторые из них скучны. Тем временем я всегда был поклонником для того, чтобы делать вещи, которые не будут сделаны другими. (Я объясню, почему другие не хотят строить редактор Markown с TKinter)

Если вы уже знакомы с Python и Tkinter, вы можете легко попасть в это руководство.

Но если вы просто начинаете с Python и/или TKinter, вы можете проверить эти: Учебники Python: TreCodecamp Python Учебник , Python 3 Playlist от Sentdex , FreeCodecamp Python для начинающих и Т. Д. (Больше можно найти один гугл) Учебники Tkinter: Основы Tkinter , FreeCodecamp Tkinter курс , Replistwoston tkinter плейлист и Т. Д. (Больше можно найти один гугл)

Итак, прежде чем мы начнем, я хочу объяснить, почему люди не хотят строить редакторов Markdown с Tkinter. Поскольку нет по умолчанию простого способа отображения HTML-вывода ввода Markdown. Там нет даже виджета TKinter по умолчанию для отображения данных HTML. Вы можете просто просто написать/редактировать markdown Но нет простого способа отображения вывода внутри вашего приложения.

Но однажды, пока я бродил на улицах Интернета, я нашел что-то интересное, tk_html_widgets Что может отображать HTML-вывод! Но, конечно, у него были некоторые проблемы: шрифты были слишком маленькими, и не было поддержки для прикрепления удаленных фотографий. Поэтому, как обычно, я создал свои собственные вилки и исправил некоторые проблемы, и вроде улучшена стабильность и названа: TKHTMLVIEW Отказ 😎

Тьфу, я думаю, что я скучаю по тебе 😅, поэтому давайте перестанем говорить и начать строить.

🛠️. Начать здание:

Сначала убедитесь, что у вас установлен Python 3 и Tkinter, если не вы можете скачать их отсюда python.org/downloads. (Tkinter уже упакован с Python).

Другие вещи, которые нам понадобятся, это TKHTMLVIEW и Markdown2. . Вы можете установить их за помощью PIP Установить TKHTMLVIEW Markdown2 или PIP3 Установить TKHTMLVIEW Markdown2 (Если у вас есть несколько версий Python)

Теперь выключите ваш любимый редактор или IDE и создайте новый файл (например, tdown.py (Я назвал редактор Twand )).

Мы начнем, импортируя необходимые библиотеки.

from tkinter import *
from tkinter import font , filedialog
from markdown2 import Markdown
from tkhtmlview import HTMLLabel

В первой строке мы импортируем все (почти) из пакета TKinter. Во второй строке мы импортируем шрифт и filedialog. шрифт необходим для стиля (например, Шрифт, размер шрифта) Наше поле ввода, и FileDialog импортируется в открытые файлы разметки файлов для редактирования и/или сохранения нашей Markdown. В 3-й строке Markdown импортируется, чтобы помочь нам преобразовать нашу нашу расчету источник на HTML и отображать в поле «Выходное поле», используя HTMLLABEL, который мы импортируем на 4-й строке.

После этого мы создадим кадр класс под названием окна, которое будет унаследовано от Tkinter Рамка Класс и удерживайте наши поля ввода и вывода.

class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.myfont = font.Font(family="Helvetica", size=14)
        self.init_window()

    def init_window(self):
        self.master.title("TDOWN")
        self.pack(fill=BOTH, expand=1)

Здесь, в этом блоке кода, мы сначала определяем окно класса, которое наследует класс виджета кадра Tkinter. Теперь в функции инициализации мы принимаем мастер в качестве аргумента, который будет служить родителем кадра, в следующей строке мы инициализируем кадр. Далее мы объявляем пользовательский объект шрифта под названием Self.myfont с семейством шрифта Helvetica (Вы можете выбрать любой шрифт семьи, которую вы хотите) и размер 14 который будет использоваться на нашей области ввода Markdown, наконец, мы называем init_window. Функция, где мы поставим сердце нашего приложения.

В init_window Функция мы впервые установили заголовок окна как Отказ А в следующей строке self.pack (заполнить = оба,) Мы говорим вашу рамку, чтобы взять полное пространство нашего окна. Мы устанавливаем заполнить Аргумент ключевых слов на Оба Что на самом деле является импортом из библиотеки Tkinter. Он говорит кадра заполнить окно как горизонтально, так и вертикально, а также Развернуть Аргумент ключевых слов установлен на 1 (означает True ) и говорит нашему кадру расширяемой, в простых терминах кадр будет заполнять окно, независимо от того, притягивается ли мы размером окна или максимизировать его.

Теперь, если вы запустите TDown.py Сценарий Вы ничего не увидите, потому что мы определили только класс, но никогда не называли это. Чтобы исправить это, мы собираемся поставить это в конце нашего сценария

root = Tk()
root.geometry("700x600")
app = Window(root)
app.mainloop()

Здесь мы создаем объект TK и хранить его в корневой переменной, которая будет служить корнем нашего окна класса. Далее мы устанавливаем геометрию нашего окна до 700×600, 700 высота и 600 ширина окна. В следующей строке вы можете увидеть, мы создаем окно объекта, нажав root Переменная как root кадра и хранение его в переменной под названием приложение Отказ Следующая вещь, которую мы делаем, это просто позвоните в функцию MainLoop, которая говорит нашему приложению! 😊.

Теперь запустите TDown.py Сценарий! Вы увидите такое пустое окно, если вы сделали все правильно:

Но это просто пустое окно, чтобы написать что-то в окне, нам нужно добавить текстовое поле, где будет написать нашу уценку. Для этого мы будем использовать Текст виджет из Tkinter.

...
def init_window(self):
    self.master.title("TDOWN")
    self.pack(fill=BOTH, expand=1)

    self.inputeditor = Text(self, width="1")
    self.inputeditor.pack(fill=BOTH, expand=1, side=LEFT)

Не путайтесь с (Три точка), я положил их там только для обозначения того, что в блоке этого кода есть несколько строк кода.

Здесь мы создаем текстовый виджет с шириной 1 Отказ Не царапайте голову, здесь выносятся изменение с использованием соотношений. Вы поймете это более четко в ближайшие несколько секунд, когда мы поставьте вывод. 😁 Затем мы упаковываем его в рамку и сообщите об этом как горизонтально, так и по вертикали.

Когда вы запускаете скрипт, вы увидите поле многослойного ввода в течение всего нашего целого Мир Окно. Если вы начнете писать в нем, вы можете заметить, что персонажи настолько крошечные!

Я уже знал, что эта проблема возникнет, поэтому я сказал вам ранее создать пользовательский объект Font ( Self.myfont ), теперь, если вы сделаете что-то подобное:

self.inputeditor = Text(self, width="1" , font=self.myfont)

(Здесь мы говорим наш текстовый виджет, чтобы использовать наш пользовательский шрифт вместо по умолчанию Tiny One!)

Размер шрифта поля ввода будет увеличен до 14. Запустите скрипт, чтобы проверить, отлично работает все!

Теперь я думаю, что пришло время добавить выводки, в котором мы увидим HTML-вывод нашей источника отметки, пока мы пишем. Для этого мы собираемся добавить HTMLLABEL что-то вроде этого внутри init_window Функция:

self.outputbox = HTMLLabel(self, width="1", background="white", html="

Welcome

") self.outputbox.pack(fill=BOTH, expand=1, side=RIGHT) self.outputbox.fit_height()

Мы используем HTMLLABEL от TKHTMLVIEW с шириной 1 (Опять же), мы устанавливаем ширину до 1, потому что окно будет совместно между полем ввода и вывода с соотношением 1: 1 (Вы поймете, что я имею в виду, когда вы пройдете скрипт). HTML Ключевое слово Аргумент хранит значение, которое будет отображаться в первый раз. Затем мы упаковываем его в окно с сторона в виде Правильно Чтобы положить это в правую сторону входного поля. и fit_height () Заставляет тексты вписываться внутри виджета (насколько я думаю 😁)

Запустите код.

Теперь, если вы начнете писать в поле ввода. Вы можете быть разочарованы (не будь!) Чтобы увидеть, что вывод не обновляется, так как мы введем, потому что мы не сказали своей программе сделать это.

Для этого мы сначала связываем событие с нашим редактором, всякий раз, когда текст изменяется, вывод будет обновлен, что-то вроде этого:

self.inputeditor.bind("<>", self.onInputChange)

Положить эту строку внутри init_window () функция

Так что в основном эта линия говорит Incomeditor позвонить в OninPutchange Функция всякий раз, когда текст изменен. Но так как у нас нет этой функции, мы собираемся написать это.

...
def onInputChange(self , event):
    self.inputeditor.edit_modified(0)
    md2html = Markdown()
    self.outputbox.set_html(md2html.convert(self.inputeditor.get("1.0" , END)))

В первой строке, используя edit_modified (0) Мы сбрасываем модифицированный флаг, чтобы его можно было повторно использовать после первого звонка события, он больше не будет работать. Затем мы создаем объект Markdown с именем MD2HTML и на последней строке, где сначала мы …. подожди! Последняя строка может быть запутана для некоторых читателей. Итак, позвольте мне сломать его на три линии.

markdownText = self.inputeditor.get("1.0" , END)
html = md2html.convert(markdownText)
self.outputbox.set_html(html)

Здесь, в первой строке, мы извлекли текст разметки сверху до нижней части входного поля. Первый аргумент Self.inputditor.get Скажите, чтобы начать сканирование от 0-го символа первой строки (1.0 => [line_number]. [CharAnce_number]), и последний аргумент позволяет прекратить сканирование при достижении конца.

Затем мы конвертируем отсканированную откидку в HTML, используя md2html.Convert () Функция и хранить его в HTML Переменная.

Наконец мы сообщим высказыванию для отображения вывода, используя .set_html. () Функция!

Запустите скрипт! Вы увидите функционирующую (почти) редактор Markowndown. Как вы вводите в поле ввода, вывод также будет обновлен!

Но… Наша работа еще не закончена. Пользователи должны быть полностью открытыми и сохранять свои тексты.

Сделать это, мы добавим Файл Меню в меню, где пользователи смогут открыть и сохранять файлы, а также выйти из приложения!

В init_window Функция мы добавим их:

self.mainmenu = Menu(self)
self.filemenu = Menu(self.mainmenu)
self.filemenu.add_command(label="Open", command=self.openfile)
self.filemenu.add_command(label="Save as", command=self.savefile)
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", command=self.quit)
self.mainmenu.add_cascade(label="File", menu=self.filemenu)
self.master.config(menu=self.mainmenu)

Я сделаю это быстро. Здесь мы определяем новое меню с рамкой как его родитель. Далее мы определяем другое меню и предыдущее меню как его родитель. Это будет служить нашим Файл меню. Затем мы добавляем 3-х меню (открыть, сохранить как, выйти) и сепаратор, используя add_command () и add_separator () Функции. Открыть Подменю будет выполнять OpenFile Функция, Сохранить как Подменю будет выполняться SaveFile функция. И, наконец, Выход будет выполнять встроенную функцию выйти который закроет программу.

Затем используя add_cascade () Функция мы говорим первый объект меню, чтобы включить Филемену Переменная, которая включает в себя все наши подмесу с этикеткой Файл Отказ Наконец мы используем self.master.config () Чтобы сказать наше окно для использования Mainmenu как меню нашего окна.

Это будет выглядеть что-то вроде этого, но еще не бегайте. Вы получите ошибки, говорящие OpenFile & SaveFile Функции не определены!

Как вы можете понять сейчас, мы должны определить две функции внутри окна класса, где мы будем использовать Tkinter Filedialog.

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

def openfile(self):
    openfilename = filedialog.askopenfilename(filetypes=(("Markdown File", "*.md , *.mdown , *.markdown"),
                                                                  ("Text File", "*.txt"), 
                                                                  ("All Files", "*.*")))
    if openfilename:
        try:
            self.inputeditor.delete(1.0, END)
            self.inputeditor.insert(END , open(openfilename).read())
        except:
            print("Cannot Open File!")     

Здесь, сначала мы показываем пользователю диалоговое окна файлового браузера, чтобы выбрать файл для открытия filedialog.askOpenFilename () Отказ С FileTypes Аргумент ключевых слов Мы говорим об этом диалоге, чтобы открыть только эти типы файлов, передав кортеж с поддерживаемыми файлами (в основном все типы файла): Разметка файлов с .md.md , .mdown , .maredown Расширения, текстовые файлы с .txt расширение, а в следующем ряду с помощью удлинения подстановки Мы говорим диалоговое окно открыть файлы с любым расширением.

Затем мы проверяем, выбрал ли пользователь файл или нет, если да, мы пытаемся открыть файл. Затем мы удаляем весь текст внутри поля ввода из 0-го символа первой линии к концу поля, затем мы открываем и прочитаем содержимое выбранного файла и вставьте содержимое в поле ввода. Если наша программа не может открыть файл, он распечатает ошибку. Но подожди, это не хороший способ обрабатывать ошибки, мы можем сделать здесь, покажет сообщение об ошибке пользователю что-то вроде этого:

Для этого мы сначала импортируем Messagebox от пакета TKinter.

from tkinter import messagebox as mbox

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

mbox.showerror("Error Opening Selected File" , "Oops!, The file you selected : {} can not be opened!".format(openfilename))

Это создаст сообщение об ошибке, как приведенный выше скриншот, я показал вам, когда файл не может быть открыт. В Mbox.showerror Функция, первый аргумент – это заголовок сообщения message, а второй – это сообщение для отображения.

Теперь нам нужно написать SaveFile Функция, чтобы сохранить нашу входную информацию.

def savefile(self):
        filedata = self.inputeditor.get("1.0" , END)
        savefilename = filedialog.asksaveasfilename(filetypes = (("Markdown File", "*.md"),
                                                                  ("Text File", "*.txt")) , title="Save Markdown File")
        if savefilename:
            try:
                f = open(savefilename , "w")
                f.write(filedata)
            except:
                mbox.showerror("Error Saving File" , "Oops!, The File : {} can not be saved!".format(savefilename))

Вот сначала мы сканируем все содержимое входного поля и храните его в переменной, затем попросите пользователя имени имя файла, чтобы сохранить содержимое в параметре для двух типов типов типов файлов (.md и .txt)

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

Не забудьте проверить ваше приложение, чтобы проверить наличие ошибок! Если вы и я и я не сделал никаких ошибок, наши программы должны работать идеально и выглядеть что-то подобное,

Полный источник этого редактора TDDOND ‘Markdown доступен в Гадость а также в Repl.it Где вы можете проверить редактор на вашем браузере!

Если вы попадаете в любые проблемы, касающиеся этой статьи, вы можете дать мне знать в комментариях или DM мне в Twitter на @bauripalash. .

Некоторые заметки:

  • Сначала помните, что это просто редактор игрушек. Если вы хотите построить более мощный редактор, вы можете использовать любые другие библиотеки GUI, такие как WxPython, Pyqt, KIVY и многие другие, которые по меньшей мере, имеют лучшую поддержку HTML ( Полный список ).

  • В этой статье я только показал, как построить Базовый Редактор, вы также можете добавить еще много классных функций, таких как экспортирование в качестве HTML или PDF, добавление кнопок для упрощения начисления записи … и т. Д.

  • Модули HTML-рендеринга TKHTMLVIEW или TK_HTML_WIDGETS не являются полностью стабильными и поддерживает только некоторые основные функции HTML, поэтому не за исключением многое.

Так… Я надеюсь, что вы наслаждались этой статьей и узнали некоторые новые вещи. Не забудьте дать мне знать, если вы застряли где-то или не можете что-то понять. Последнее, но не менее важное, пожалуйста, дайте мне знать, если я сделал какие-либо ошибки выше и ваши идеи или предложения через комментарии или DM.

Спасибо. 👻

Оригинал: “https://dev.to/bauripalash/let-s-create-a-toy-markdown-editor-with-python-tkinter-13nk”