Nano Hash - криптовалюты, майнинг, программирование

Перенаправление «stdout» на несколько виджетов с прокручиваемым текстом?

У меня есть 3 виджета Tkinter с прокруткой, и я хочу перенаправлять текст на каждый из них независимо.

Первый текст из func1 я могу напечатать в текстовое поле, используя stdout, второй — func2, используя stderr, но как напечатать столько функций, сколько я хочу, в несколько текстовых полей, потому что, если я буду использовать stdout для всех этих трех функций он напечатает эти 3 функции только в третье текстовое поле и пропустит делегаты для txt1 и txt2, но я хочу, чтобы вывод в каждое текстовое поле был независимым.

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

В настоящее время он будет печатать текст из func1 в txt1, из func2 в txt2 и снова из func3 в txt2, но он должен печатать его в txt3.

class app_app(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.txt1 = scrolledtext.ScrolledText(self)
        self.txt1.place()

        self.txt2 = scrolledtext.ScrolledText(self)
        self.txt2.place()

        self.txt3 = scrolledtext.ScrolledText(self)
        self.txt3.place()

        b = tk.Button(self, text="run", command=self.func1)
        b.place()
        b1 = tk.Button(self, text="run", command=self.func2)
        b1.place()
        b2 = tk.Button(self, text="run", command=self.func3)
        b2.place() 

       sys.stdout = TextDump(self.txt1, "stdout")
       sys.stderr = TextDump(self.txt2, "stderr")
       sys.stderr = TextDump(self.txt3, "stderr")

   def func1(self):
       print("func1 print")

   def func2(self):
       print("func2 print")

   def func3(self):
       print("func3 print") 


class TextDump(object):
     def __init__(self, widget, tag="stdout"):
         self.widget = widget
         self.tag = tag

     def write(self, str):
         self.widget.configure(state="normal")
         self.widget.insert("end", str, (self.tag,))

     def flush(self):
         pass
app = app_app()
app.mainloop()

  • Зачем вам нужно использовать перенаправление здесь? Почему бы просто не написать func1, func2 и func3 непосредственно в соответствующий виджет? 15.10.2018
  • Потому что без перенаправления все эти отпечатки будут идти в консоль, а не в текстовые поля. 15.10.2018
  • Если вы действительно хотите сделать это с помощью перенаправления, одним из способов было бы создать другой TextDump-подобный класс (или обобщить тот, который у вас уже есть), который позволял писать в два (или более) ScrolledText виджета, используя его метод write() для вставки любого полученного вывода. во все из них... немного похоже на то, что делает команда Linux tee. 15.10.2018
  • @NickPV: ты упустил суть моего вопроса. Почему требуется перенаправление? Почему вы должны использовать оператор print вместо метода insert виджета, который вы тоже хотите написать? Почему вам нужно использовать оператор print? 15.10.2018
  • @BryanOakley Мне нужно использовать перенаправление, потому что это приложение построено так, есть функция, которую можно вызывать из этого пользовательского интерфейса, и некоторая функция может содержать печать построчно, и каждая такая строка будет выводиться на консоль, но я хочу поймать ее раньше и добавить в текстовое поле в пользовательском интерфейсе, поэтому я не могу просто печатать в функции, но также должен ожидать некоторых отпечатков в сторонних функциях. 16.10.2018
  • @BryanOakley Другими словами, я не знаю, как реализовать это с Tkinter без перенаправления, надеюсь, вы понимаете, чего я пытаюсь достичь. Спасибо 16.10.2018

Ответы:


1

Одно предложение: удалить TextDump. Вместо этого добавьте метод записи в ScrolledText (или, что лучше, его подкласс) и используйте опцию file= вызовов печати. Увеличение ScrolledText и игнорирование тегов:

# Before app_app.
def write(self, text):
    self.insert("end", text)
ScrolledText.write = write

    # Within app_app, replace current func1/2/3 defs.
    def func1(self):
        print("func1 print", file=self.txt1)

Для целей print файл — это объект с методом .write.

>>> class Writable:
    def write(self, string): print(self, string)

>>> print('hello', file=Writable())
<__main__.Writable object at 0x000002518B289F60> hello
<__main__.Writable object at 0x000002518B289F60>      # \n
15.10.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..