Во время посмотра группы wxPython в Google или StackOverflow, я получил много интересных идей. В один прекрасный день, я увидел тему, в которой кто-то спрашивал о том, как заставить модуль логгинга Python вывести данные в файл и в TextCtrl.
Похоже, что вам нужно будет создать обычный хэндлер логгинга, чтобы сделать это. Сначала, я пытался использовать нормальный StreamHandler и перенаправлять stdout через модуль sys (sys.stdout) в мой текстовый контроль, но он перенаправлял только напечатанные утверждения, а не сообщения лога.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Давайте посмотрим на то, к чему я пришёл
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
import logging import logging.config import wx class CustomConsoleHandler(logging.StreamHandler): """""" def __init__(self, textctrl): """""" logging.StreamHandler.__init__(self) self.textctrl = textctrl def emit(self, record): """Constructor""" msg = self.format(record) self.textctrl.WriteText(msg + "\n") self.flush() class MyPanel(wx.Panel): """""" def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent) self.logger = logging.getLogger("wxApp") self.logger.info("Test from MyPanel __init__") logText = wx.TextCtrl( self, style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL) btn = wx.Button(self, label="Press Me") btn.Bind(wx.EVT_BUTTON, self.onPress) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(logText, 1, wx.EXPAND|wx.ALL, 5) sizer.Add(btn, 0, wx.ALL, 5) self.SetSizer(sizer) txtHandler = CustomConsoleHandler(logText) self.logger.addHandler(txtHandler) def onPress(self, event): """ On the press of a button, log some messages """ self.logger.error("Error Will Robinson!") self.logger.info("Informational message") class MyFrame(wx.Frame): """""" def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Logging test") panel = MyPanel(self) self.logger = logging.getLogger("wxApp") self.Show() def main(): """ Запускаем программу """ dictLogConfig = { "version":1, "handlers":{ "fileHandler":{ "class":"logging.FileHandler", "formatter":"myFormatter", "filename":"test.log" }, "consoleHandler":{ "class":"logging.StreamHandler", "formatter":"myFormatter" } }, "loggers":{ "wxApp":{ "handlers":["fileHandler", "consoleHandler"], "level":"INFO", } }, "formatters":{ "myFormatter":{ "format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s" } } } logging.config.dictConfig(dictLogConfig) logger = logging.getLogger("wxApp") logger.info("This message came from main!") app = wx.App(False) frame = MyFrame() app.MainLoop() if __name__ == "__main__": main() |
Вы заметите, что я остановился на использовании модуля logging.config. Метод dictConfig был добавлен в Python 2.7. Проще говоря, вы настраиваете ваш хэндлер логгинга и форматтеры и всё, что не находится в словаре, а затем пропускаете это через logging.config.
Если вы запустите этот код, то заметите, что первые несколько сообщений отправятся в stdout и в лог, но не в текстовый контроль. В конце панельного класса __init__ мы добавляем обычный хэндлер, и вот здесь как раз начинается перенаправление сообщений логгинга в текстовый контроль. Вы можете нажать на кнопку, чтобы увидеть всё это в действии!
Вот как это выглядело на моём компьютере:
Вы заметите, что сможете увидеть информацию о логгинге в stdout и в нашем текстовом контроле на скриншоте. Вы должны увидеть что-то подобное в вашем терминале и файле лога:
1 2 3 |
2016-11-30 14:04:35,026 - wxApp - INFO - This message came from main! 2 2016-11-30 14:04:35,026 - wxApp - INFO - Test from MyPanel __init__ 3 2016-11-30 14:04:38,261 - wxApp - ERROR - Error Will Robinson! |
Итоги
Теперь вы знаете как перенаправлять методы логгинга Python в виджет wxPython, а именно в wx.TextCtrl. Это может прийтись очень кстати, если вы захотите сохранить выходные данные из приложения в отдельный файл, а не только просматривать их в режиме реального времени. В следующей статье, мы рассмотрим то, как перенаправить stdout в wx.TextCtrl!
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»