Как я могу отправить многопроцессорную обработку процесса python на Tkinter gui

Я пытаюсь получить выход из процесса многопроцессорности python, отображаемого в Tkinter gui.

Я могу отправить вывод из процессов через gui в командную оболочку, например, запустив fllowing small-script скрипт в командной строке:

  • Отображение и скрытие виджетов
  • Tkinter только вызывает after_idle один раз
  • Простой, универсальный и повторно используемый диалог ввода (иногда называемый диалогом ввода) в PyGTK
  • Python 3 Как получить изображение из Интернета и отобразить его в графическом интерфейсе с помощью TKINTER?
  • Почему я не могу вставлять выходные данные Pythons REPL без ручного редактирования?
  • Применение Matlotlib Crashing tkinter
  • from multiprocessing import Process import sys def myfunc(text): print text sys.stdout.flush() def f1(): p1 = Process(target = myfunc, args = ("Surprise",)) p1.start() def f2(): p2 = Process(target = myfunc, args = ("Fear",)) p2.start() def fp(): myfunc("... and an almost fanatical devotion to the Pope") a = Tk() b1 = Button(a, text="Process 1", command=f1) b1.grid(row=0, column=0, pady=10, padx=10, sticky=SE) b2 = Button(a, text="Process 2", command=f2) b2.grid(row=0, column=1, pady=10, padx=10, sticky=SE) b3 = Button(a, text="Parent", command=fp) b3.grid(row=0, column=2, pady=10, padx=10, sticky=SE) if __name__ == "__main__": a.mainloop() 

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

     # sys.stdout.flush() 

    и добавив сразу после строки «b3.grid …» следующее:

     class STDText(Text): def __init__(self, parent, cnf={}, **kw): Text.__init__(self, parent, cnf, **kw) def write(self, stuff): self.config(state=NORMAL) self.insert(END, stuff) self.yview_pickplace("end") self.config(state=DISABLED) messages = STDText(a, height=2.5, width=30, bg="light cyan", state=DISABLED) messages.grid(row=1, column=0, columnspan=3) sys.stdout = messages 

    Однако я не могу понять, как отправить вывод из Процессов в текстовое поле. Я что-то пропустил?

  • Как мне сделать быстрое развитие графического интерфейса для методов R и Octave (возможно, с Python)?
  • Maya python UI - локальная переменная, не определенная ошибка при использовании внутри кнопки кнопки внутри одной и той же функции
  • Есть ли какие-нибудь «полезные программы» для инструментальных средств GUI для Python?
  • Подробнее о Python TKinter Dynamic OptionMenu
  • Tkinter только вызывает after_idle один раз
  • DestroyWindow не закрывает окно на Mac с помощью Python и OpenCV
  • 3 Solutions collect form web for “Как я могу отправить многопроцессорную обработку процесса python на Tkinter gui”

    Вы можете перенаправить stdout / stderr на StringIO в myfunc (), а затем отправить все, что будет записано в этот StringIO, обратно родительскому (как было предложено unutbu). См. Мой ответ на этот вопрос для одного из способов сделать это перенаправление.

    Поскольку этот пример немного больше, чем вам нужно, вот версия, которая больше соответствует вашим заявленным целям:

     #!/usr/bin/env python import sys from cStringIO import StringIO from code import InteractiveConsole from contextlib import contextmanager from multiprocessing import Process, Pipe @contextmanager def std_redirector(stdin=sys.stdin, stdout=sys.stdin, stderr=sys.stderr): tmp_fds = stdin, stdout, stderr orig_fds = sys.stdin, sys.stdout, sys.stderr sys.stdin, sys.stdout, sys.stderr = tmp_fds yield sys.stdin, sys.stdout, sys.stderr = orig_fds class Interpreter(InteractiveConsole): def __init__(self, locals=None): InteractiveConsole.__init__(self, locals=locals) self.output = StringIO() self.output = StringIO() def push(self, command): self.output.reset() self.output.truncate() with std_redirector(stdout=self.output, stderr=self.output): try: more = InteractiveConsole.push(self, command) result = self.output.getvalue() except (SyntaxError, OverflowError): pass return more, result def myfunc(conn, commands): output = StringIO() py = Interpreter() results = "" for line in commands.split('\n'): if line and len(line) > 0: more, result = py.push(line + '\n') if result and len(result) > 0: results += result conn.send(results) conn.close() if __name__ == '__main__': parent_conn, child_conn = Pipe() commands = """ print "[42, None, 'hello']" def greet(name, count): for i in range(count): print "Hello, " + name + "!" greet("Beth Cooper", 5) fugazi print "Still going..." """ p = Process(target=myfunc, args=(child_conn, commands)) p.start() print parent_conn.recv() p.join() 

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

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

     def dosomething(): print "Doing something..." def myfunc(conn, command): output = StringIO() result = "" with std_redirector(stdout=output, stderr=output): try: eval(command) result = output.getvalue() except Exception, err: result = repr(err) conn.send(result) conn.close() if __name__ == '__main__': parent_conn, child_conn = Pipe() command = "dosomething()" p = Process(target=myfunc, args=(child_conn, command)) p.start() print parent_conn.recv() p.join() 

    Вы можете передавать (picklable) данные между процессами с использованием multiprocessing.Pipe . Например:

     import Tkinter import multiprocessing as mp class STDText(Tkinter.Text): def __init__(self, parent, cnf={}, **kw): Tkinter.Text.__init__(self, parent, cnf, **kw) def write(self, stuff): self.config(state=Tkinter.NORMAL) self.insert(Tkinter.END, stuff) self.yview_pickplace("end") self.config(state=Tkinter.DISABLED) def myfunc(conn,text): conn.send(text) conn.close() class Gui(object): def __init__(self): self.a=Tkinter.Tk() b1=Tkinter.Button(self.a, text="Process 1", command=self.foo) b1.grid(row=0, column=0, pady=10, padx=10, sticky=Tkinter.SE) b2=Tkinter.Button(self.a, text="Process 2", command=self.bar) b2.grid(row=0, column=1, pady=10, padx=10, sticky=Tkinter.SE) b3=Tkinter.Button(self.a, text="Parent", command=self.baz) b3.grid(row=0, column=2, pady=10, padx=10, sticky=Tkinter.SE) self.messages=STDText( self.a, height=2.5, width=30, bg="light cyan", state=Tkinter.DISABLED) self.messages.grid(row=1, column=0, columnspan=3) self.a.mainloop() def call_myfunc(self,text): parent_conn, child_conn=mp.Pipe() proc=mp.Process(target=myfunc, args=(child_conn,text,)) proc.start() self.messages.write(parent_conn.recv()) proc.join() def foo(self): self.call_myfunc('Foo\n') def bar(self): self.call_myfunc('Bar\n') def baz(self): parent_conn, child_conn=mp.Pipe() myfunc(child_conn,'Baz\n') self.messages.write(parent_conn.recv()) if __name__ == "__main__": Gui() 

    Дополнительную информацию см. В руководстве Doug Hellman по multiprocessing .

    Предполагая, что myfunc вызывается с выходом процесса, просто напишите myfunc как:

     def myfunc(text): textwidget.insert("end", text) 

    где textwidget – это дескриптор текстового виджета

    Python - лучший язык программирования в мире.