Окна TKinter не появляются при использовании многопроцессорной обработки в Linux
-
03-07-2019 - |
Вопрос
Я хочу запустить другой процесс для асинхронного отображения сообщения об ошибке, пока остальная часть приложения продолжает работать.
я использую multiprocessing
модуль в Python 2.6 для создания процесса, и я пытаюсь отобразить окно с помощью TKinter
.
Этот код нормально работал в Windows, но запуск его в Linux TKinter
окно не появляется, если я звоню 'showerror("MyApp Error", "Something bad happened.")'
.Это делает появится, если я запущу его в том же процессе, вызвав showerrorprocess
напрямую.Учитывая это, кажется TKinter
работает правильно.Я могу печатать на консоли и делать другие вещи из процессов, порожденных multiprocessing
, так что, похоже, это тоже работает.
Кажется, они просто не работают вместе.Нужно ли мне делать что-то особенное, чтобы позволить порожденным подпроцессам создавать окна?
from multiprocessing import Process
from Tkinter import Tk, Text, END, BOTH, DISABLED
import sys
import traceback
def showerrorprocess(title,text):
"""Pop up a window with the given title and text. The
text will be selectable (so you can copy it to the
clipboard) but not editable. Returns when the
window is closed."""
root = Tk()
root.title(title)
text_box = Text(root,width=80,height=15)
text_box.pack(fill=BOTH)
text_box.insert(END,text)
text_box.config(state=DISABLED)
def quit():
root.destroy()
root.quit()
root.protocol("WM_DELETE_WINDOW", quit)
root.mainloop()
def showerror(title,text):
"""Pop up a window with the given title and text. The
text will be selectable (so you can copy it to the
clipboard) but not editable. Runs asynchronously in
a new child process."""
process = Process(target=showerrorprocess,args=(title,text))
process.start()
Редактировать
Проблема, кажется, в том, что TKinter
был импортирован родительским процессом и «унаследован» дочерним процессом, но каким-то образом его состояние неразрывно связано с родительским процессом и не может работать в дочернем процессе.Пока вы убедитесь, что не импортируете TKinter
прежде чем вы создадите дочерний процесс, он будет работать, потому что тогда именно дочерний процесс импортирует его в первый раз.
Решение
Этот обсуждение может быть полезно.
Вот несколько примеров проблем, которые я обнаружил:
Хотя модуль многопроцессорности точно следует за потоками, он определенно не является точным совпадением.Один пример:Поскольку параметры процесса должны быть маринованный, Мне пришлось пройти много изменений кода, чтобы избежать прохождения
Tkinter
объекты, поскольку они не являются маринованный.Этого не происходит с модулем потоковой передачи.
process.terminate()
не работает после первой попытки.Вторая или третья попытка просто вешает интерпретатора, вероятно, потому, что структуры данных повреждены (упоминаются в API, но это мало утешительно).
Другие советы
Возможно, вызов команды оболочки xhost +
прежде чем вызов вашей программы из той же оболочки будет работать?
Я предполагаю, что ваша проблема связана с X-сервером.