Возможен ли многопроцессный ткинтер? - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь мультипроцессировать несколько окон tkinter, где потребуется многопоточность (для длительных процессов с циклами while) в каждом процессе.Это возможно?

Я пытался обойти это, выполняя чисто многопоточную реализацию - все приложение начинает становиться «запаздывающим»;отсюда и попытка сейчас сделать многопроцессорность.Пожалуйста, смотрите код для очень упрощенной, базовой версии того, что я пытаюсь сделать.Существует 2 сценария:

Основной файл (для запуска)

from tkinter import *
from tkinter import ttk
import threading
import multiprocessing
import multiprocessing_import_worker

def hello():
    if __name__ == '__main__':
        p_list = ["Hello", "success"]
        p = multiprocessing.Process(target=multiprocessing_import_worker.worker, args=p_list)
        p.start()
        root.destroy()

root = Tk()
root.title("Window 1")

statusFrame = Frame(root)
statusFrame.pack()
statusLabelFrame = LabelFrame(statusFrame, text='TEST FRAME', font="Helvetica 8 bold")
statusLabelFrame.pack(fill="both", expand="yes", padx="7")
firstButtonFrame = Frame(root)
firstButtonFrame.pack()
statusbar = Label(statusLabelFrame, text="TEST", width=40, font="Helvetica 8 bold")
statusbar.pack()
b1=ttk.Button(firstButtonFrame, text="START SESSION", width=15, command=hello)
b1.pack(pady=(10,0))

root.mainloop()

Вторичный файл (для запуска в качестве отдельного процесса)

def worker(word, word2):
    import threading
    import tkinter as tk
    from tkinter import ttk
    import os

    print(word)
    print(word2)

    def testThread():
        global word
        global word2
        print(word)
        print(word2)

    root = tk.Tk()
    root.withdraw()
    rootWindow = tk.Toplevel()
    rootWindow.title("Window 2")

    statusFrame = tk.Frame(rootWindow)
    statusFrame.pack()
    statusLabelFrame = tk.LabelFrame(statusFrame, text='TEST FRAME', font="Helvetica 8 bold")
    statusLabelFrame.pack(fill="both", expand="yes", padx="7")
    firstButtonFrame = tk.Frame(rootWindow)
    firstButtonFrame.pack()
    statusbar = tk.Label(statusLabelFrame, text="TEST", width=40, font="Helvetica 8 bold")
    statusbar.pack()
    b1=ttk.Button(firstButtonFrame, text="START SESSION", width=15, state='disabled')
    b1.pack(pady=(10,0))

    child_thread1 = threading.Thread(target=testThread)
    child_thread1.start()

    rootWindow.protocol("WM_DELETE_WINDOW", os._exit(0))
    rootWindow.mainloop()

Ожидаемые результаты :

  • Появится всплывающее окно tkinter под названием «Window 1»
  • После нажатия кнопки START SESSION, «Window»1 "уничтожается (закрывается).
  • " Окно 2 "(которое выглядит точно так же) затем всплывает, с отключенной кнопкой START SESSION.
  • Нажатие крестика в верхней правой рукеугол закрывает «Окно 2» и завершает приложение.

Фактические результаты :

  • Всплывающее окно tkinter под названием «Окно 1»
  • После нажатия кнопки START SESSION «Окно 1» разрушается (закрывается).
  • Затем всплывает еще одно «Окно 1» (которое выглядит точно так же), с включенной кнопкой START SESSION не отображается.на любую команду.
  • Нажатие крестика в правом верхнем углу закрывает «Окно 1» и завершает приложение.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

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

0 голосов
/ 01 февраля 2019

Это возможно, но все взаимодействие с GUI должно происходить в одном процессе.Сам Tkinter не может охватывать ни процессы, ни потоки.Ваши другие процессы должны поместить работу в очередь, которую периодически обрабатывает и обрабатывает процесс tkinter (конечно, вы также можете обмениваться данными с любой другой формой IPC).

Причина этого заключается в том, что каждое корневое окно связано со встроенным интерпретатором tcl, и сам этот интерпретатор не может охватывать процессы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...