Я создаю текстовый виджет tkinter и хочу перенаправить sys.stdout на текстовый виджет. Частично я выполнил эту функцию, но столкнулся с проблемой многопроцессорности.
Ниже приведена игрушка Python 3, с которой вы можете играть,
import sys
import tkinter as tk
from multiprocessing import Pool
root = tk.Tk()
root.geometry('600x400+30+30')
textArea = tk.Text(root, bg='gray', width=70, height=20)
textArea.pack()
tk.Button(root, text='click me', command=lambda: print('Dont touch\n me!')).pack()
class redirectStd():
def __init__(self, textWidget):
self.textBoard = textWidget
self.flush = sys.stdout.flush
def write(self, msg):
self.textBoard.insert('end', msg)
sys.stdout = redirectStd(textArea)
sys.stderr = redirectStd(textArea)
def f(x):
print('calculate:', x, '** 2')
return x ** 2
def testParallel():
print('start testing')
with Pool(processes=2) as p:
res = p.map(f, [1, 4, 0, 7, 3, 5])
print(res)
tk.Button(root, text='test multiprocessing', command=testParallel).pack()
root.mainloop()
Это будет работать правильно. Однако печать в def f(x)
ничего не напечатает в текстовом виджете.
Если комментарий self.flush = sys.stdout.flush
в блоке class redirectStd
вызовет ошибку, которая жалуется на flush undefined в redirectStd. На данном этапе я не нашел, как определить метод flush для redirectStd. Полное сообщение об ошибке
start testing
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/zsf/miniconda3/lib/python3.6/tkinter/__init__.py", line 1699, in __call__
return self.func(*args)
File "test.py", line 28, in testParallel
with Pool(processes=2) as p:
File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/context.py", line 119, in Pool
context=self.get_context())
File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/pool.py", line 168, in __init__
self._repopulate_pool()
File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/pool.py", line 233, in _repopulate_pool
w.start()
File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/process.py", line 105, in start
self._popen = self._Popen(self)
File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/context.py", line 277, in _Popen
return Popen(process_obj)
File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/popen_fork.py", line 17, in __init__
sys.stdout.flush()
AttributeError: 'redirectStd' object has no attribute 'flush'
Может ли кто-нибудь дать намек на решение для этого? Спасибо!
#self.flush = sys.stdout.flush
, чтобы он работал правильно. Однакоprint('calculate: ', x, '** 2')
ничего не печатает. Есть ли у вас какие-либо дополнительные советы? Кстати, я тестирую это на macOS 10.12.6. 04.08.2017