Извлекаем XML из RichTextCtrl — wxPython #24

RichTextCtrl даёт вам возможность использовать стилизованный текст. Он также предоставляет несколько разных хэндлеров для сохранения данных, которые размещаются в нём в разных форматах. Одним из них оказался XML. В данном рецепте мы узнаем, как извлечь XML из RichTextCtrl.

Извлекаем XML

RichTextCtrl является частью wx.richtext, который вам нужно будет импортировать в дополнение к модулю wx. Будет намного понятнее, если мы рассмотрим это на простом примере:

Давайте сделаем небольшой перерыв. Сначала мы создаём наше миленькое приложение, а затем добавляем инстанцию виджета RichTextCtrl во фрейм, наряду с кнопкой, позволяющей сохранить всё, чтобы мы не вписывали в виджет. Затем мы задаём биндинг этой кнопки и расположение виджета. Последним шагом будет создание нашего хэндлера событий. И вот здесь как раз и происходит всё самое интересное. Здесь мы создаём RichTextXMLHandler и захватываем буффер RichTextCtrl, и, благодаря этим действиям, мы можем вводить свои данные.

Есть вопросы по Python?

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

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Но вместо того, чтобы вписывать в сам файл, мы вписываем в объект подобный файлу, который является инстанцией StringIO. Мы делаем это, чтобы данные можно было как вводить в память, так и извлекать из неё. Мы делаем это лишь потому, что пользователь StackOverflow хотел найти способ извлечения XML, генерируемый RichTextCtrl, а затем вносить его в базу данных. Мы могли записать это в файл на диске, а затем считать его, но предложенный мной способ гораздо менее суетливый и более быстрый.

Учтите, что если вы собираетесь вписать в RichTextCtrl целую поэму, то это явно ПЛОХАЯ идея. Судя по тому, что вы до сих пор не выбежали из комнаты, у вас на компьютере наверняка есть масса файлов, которые превышают его память. Если вы знаете, что файл, который вы собираетесь загружать займёт очень много памяти, вы вряд ли решитесь на его запуск. Вместо этого вы предпочтёте считывать и записывать данные более мелкими фрагментами. В любом случае, код выполняет ту задачу, которую мы перед собой ставили. Я надеюсь, что вам это пригодится. По крайней мере, я получал удовольствие пока разбирался в этом всём.

К сожалению, пример данного кода не работает с wxPython Phoenix. В следующем фрагменте статьи, мы исправим данную оплошность, слегка изменив код.

Обновление для Phoenix

Первая проблема, с которой вы столкнётесь, запуская пример кода, записанный выше в Phoenix – метод SaveStream прекратил своё существование. Вам нужно будет использовать метод SaveFile вместо него. Ещё одна проблема, на самом деле, была вызвана Python 3. Если вы запустите этот код в Python 3, вы обнаружите, что модуля StringIO больше не существует, и вам нужно использовать модуль io в качестве замены. Так что, пример кода, который вы видите ниже, был обновлён мной, так что он без проблем запускается и на Python 3, и на wxPython Phoenix. Давайте же взглянем на основные отличия.

Главные отличия расположены в секциях импорта в самом начале кода, и в методе on_save. Вы заметите, что я использовал класс модуля io, который называется BytesIO. Затем мы захватываем все данные также, как мы делали это раньше, лишь с одним отличием: SaveStream был заменён SaveFile. XML, который распечатывается, является двоичным стрингом, так что если вы собираетесь его парсить, то результат парсинга лучше поместить в стринг. Я часто встречаю XML парсеры, которые напрочь отказываются корректно обрабатывать бинарные стринги.

Итоги

Конечно, написанный мной код подходит только для извлечения XML, но вы можете быстро и просто расширить его функционал таким образом, что он сможет извлекать и другие форматы, поддерживаемые RichTextCtrl, такие как HTML или сам Rich Text Format (RTF). Это может стать полезным инструментом, если вам нужно сохранять данные из вашего приложения в стороннюю базу данных или другое хранилище.