ошибка "cannot pickle '_tkinter.tkapp' object" при использовании Multiprocessing

HEKOPEKTHbIU

Новичок
Пользователь
Дек 5, 2024
1
0
1
Здравствуйте! Пишу программу с помощью графического модуля tkinter. Столкнулся с проблемой невозможности передачи виджетов в функции, которые запускаю в параллельном процессе через класс Process. Выдает ошибку "cannot pickle '_tkinter.tkapp' object". Тот же самый код нормально работает в библиотеке threading, но в ней нельзя принудительно остановить непрерывный процесс. Не понимаю почему в Thread все работает, а в Process - нет. Есть мысли?
python 3.11.9 64bit Windows
tkinter Tcl/Tk 8.6.12


Python:
import time
import multiprocessing
from threading import Thread
from tkinter import *
from tkinter import ttk

# Модуль Multiprocessing и Thread, пока работает только так...
# Функция контроля работы потока расчета
def live(t1,w):
    while t1.is_alive():
        print("Ok")
        time.sleep(0.2)
    else:
        w.destroy()
# Функция счета
def s4et(k):
    i=0
    while i<10**1:
        i+=1
        d=i*k
        print(d)
        time.sleep(0.5)
# Функция открытия окна при расчете
def pusk():
    # Функция закрытия окна по нажатию кнопки
    def denide():
        t1.terminate()
        window.destroy()    # Закрытие окна
    # Новое вспомогательное окно
    window=Toplevel()
    window.geometry(f"{int(wtk/2)}x{int(htk/2)}+{int(w_wtk+wtk/4)}+{int(w_htk+htk/4)}")
   
    btn1=Button(master=window,text="Stop",cursor="hand2",border=4,command=denide,activebackground="white",activeforeground="black",bd=5,font=("Times","12"))
    btn1.pack(anchor='sw',pady=5,padx=0)
    t1=multiprocessing.Process(target=s4et,args=(2,),daemon=True) # Поток
    t2=Thread(target=live,args=(t1,window),daemon=True) # работает
    t3=multiprocessing.Process(target=live,args=(t1,window),daemon=True) # не работает
    t1.start() # Запуск потока расчета
    t2.start() # Запуск потока контроля
    t3.start() # Запуск потока контроля
    window.mainloop()

if __name__ == '__main__':
    root=Tk()
    # Размер и положение окна
    wtk=500
    htk=500
    w_wtk=root.winfo_screenwidth()          # Определение разрешения экрана по ширине
    w_htk=root.winfo_screenheight()         # Определение разрешения экрана по высоте
    w_wtk=w_wtk//2-wtk/2                      # Определение координат середины экрана по ширине
    w_htk=w_htk//2-htk/2                      # Определение координат середины экрана по высоте
    root.geometry(f"{wtk}x{htk}+{int(w_wtk)}+{int(w_htk)}")     # Размер и положение окна
    # Надписи
    lbl_res=Label(master=root,text="Запуск расчета")
    # Кнопка запуска расчета
    btn1=Button(master=root,text="ПУСК!",cursor="hand2",border=4,command=lambda:pusk(lbl_vivod),
                        activebackground="white",activeforeground="black",bd=5,font=("Times","12"))
    # Размещение виджетов
    lbl_res.pack(pady=5)
    btn1.pack(anchor='center',pady=50,padx=0)
    root.mainloop()
 

Форум IT Специалистов