Окна TKinter не появляются при использовании многопроцессорной обработки в Linux

StackOverflow https://stackoverflow.com/questions/410469

Вопрос

Я хочу запустить другой процесс для асинхронного отображения сообщения об ошибке, пока остальная часть приложения продолжает работать.

я использую 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 прежде чем вы создадите дочерний процесс, он будет работать, потому что тогда именно дочерний процесс импортирует его в первый раз.

Это было полезно?

Решение

Этот обсуждение может быть полезно.

Вот несколько примеров проблем, которые я обнаружил:

  1. Хотя модуль многопроцессорности точно следует за потоками, он определенно не является точным совпадением.Один пример:Поскольку параметры процесса должны быть маринованный, Мне пришлось пройти много изменений кода, чтобы избежать прохождения Tkinter объекты, поскольку они не являются маринованный.Этого не происходит с модулем потоковой передачи.

  2. process.terminate() не работает после первой попытки.Вторая или третья попытка просто вешает интерпретатора, вероятно, потому, что структуры данных повреждены (упоминаются в API, но это мало утешительно).

Другие советы

Возможно, вызов команды оболочки xhost + прежде чем вызов вашей программы из той же оболочки будет работать?

Я предполагаю, что ваша проблема связана с X-сервером.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top