ForkingPickler(file, protocol).dump(obj) TypeError: 无法 pickle '_tkinter.tkapp' 对象



下面是我的代码,我的函数从服务器接收数据块,并将它们放入FIFO缓冲区,然后并行调用两个函数,

recvData(( #继续从服务器接收数据块并放入FIFO缓冲区
calculate_threshold((#从FIFO缓冲区中删除数据块并执行一些计算,在GUI上实时显示,并将结果写入文件

代码


import socket
import turtle
#import timeit
import queue
import multiprocessing
from tkinter import *
class GUI:
def __init__(self, master):
self.master = master
master.title("Collision Detection")

self.buff_data = queue.Queue()
self.p1 = multiprocessing.Process(target = self.recvData)
self.p1 = multiprocessing.Process(target=self.calculate_threshold)

self.input_label = Label(root, text = "Input all the gratings set straight wavelength values in nm")
self.input_label.grid(row = 0)

self.core_string = "Core "
self.entries = []
self.label_col_inc = 0
self.entry_col_inc = 1
self.core_range = range(1, 5)
for y in self.core_range:
self.core_text = self.core_string + str(y) + '_' + '25'
self.core_label = Label(root, text = self.core_text)
self.entry = Entry(root)
self.core_label.grid(row=1, column=self.label_col_inc, sticky=E)
self.entry.grid(row=1, column=self.entry_col_inc)
self.entries.append(self.entry)
self.label_col_inc += 2
self.entry_col_inc += 2

self.threshold_label = Label(root, text = "Threshold in nm")
self.entry_threshold = Entry(root)
self.threshold_label.grid(row = 2, sticky = E)
self.entry_threshold.grid(row = 2, column = 1)

self.light_label = Label(root, text = 'Status')
self.light_label.grid(row = 3, column = 3)
self.canvas = Canvas(root, width = 150, height = 50)
self.canvas.grid(row = 4, column = 3)

# Green light
self.green_light = turtle.RawTurtle(self.canvas)
self.green_light.shape('circle')
self.green_light.color('grey')
self.green_light.penup()
self.green_light.goto(0,0)
# Red light
self.red_light = turtle.RawTurtle(self.canvas)
self.red_light.shape('circle')
self.red_light.color('grey')
self.red_light.penup()
self.red_light.goto(40,0)

self.data_button = Button(root, text = "Get data above threshold", command = self.getData)
self.data_button.grid(row = 5, column = 0)

# function to receive TCP data blocks
def getData(self):
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.connect((host, port))
len_message = s.recv(4)
bytes_length = int(len_message.decode('utf-8'))  # for the self-made server
recvd_data = s.recv(bytes_length)
self.buff_data.put(recvd_data)
self.p1.start()
self.p2.start()
self.p1.join()
self.p2.join()

def recvData(self):
len_message = s.recv(4)
while len_message:
bytes_length = int(len_message.decode('utf-8'))  # for the self-made server
recvd_data = s.recv(bytes_length)
self.buff_data.put(recvd_data)
len_message = s.recv(4)
else:
print('out of loop')
s.close()

def calculate_threshold(self):
rmv_data = self.buff_data.get()
stringdata = rmv_data.decode('utf-8')
rep_str = stringdata.replace(",", ".")
splitstr = rep_str.split()
# received wavelength values
inc = 34
wav_threshold = []
for y in self.entries:
straight_wav = float(y.get())
wav = float(splitstr[inc])
wav_diff = wav - straight_wav
if wav_diff < 0:
wav_diff = wav_diff * (-1)
wav_threshold.append(wav_diff)
inc += 56
threshold = float(self.entry_threshold.get())
# writing into the file
data = []
inc1 = 0
col1 = 2
col2 = 6
data.insert(0, (str(splitstr[0])))
data.insert(1, (str(splitstr[1])))
for x in wav_threshold:
if (x > threshold):
self.red_light.color('red')
self.green_light.color('grey')
data.insert(col1, (str(splitstr[34 + inc1])))
data.insert(col2,(str(x)))
else:
self.red_light.color('grey')
self.green_light.color('green')
data.insert(col1,'-')
data.insert(col2,'-')
inc1 += 56
col1 += 1
col2 += 1
self.write_file(data)

# function to write into the file
def write_file(self,data):
with open("Output.txt", "a") as text_file:
text_file.write('t'.join(data[0:]))
text_file.write('n')
if __name__ == '__main__':
root = Tk()
gui = GUI(root)
root.mainloop()

但我得到以下错误:


Exception in Tkinter callback
Traceback (most recent call last):
File "C:UsersAppDataLocalProgramsPythonPython38-32libtkinter__init__.py", line 1883, in __call__
return self.func(*args)
File "C:/Users/PycharmProjects/GUI/GUI_v4.py", line 88, in getData
self.p1.start()
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingprocess.py", line 121, in start
self._popen = self._Popen(self)
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingcontext.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingcontext.py", line 326, in _Popen
return Popen(process_obj)
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingpopen_spawn_win32.py", line 93, in __init__
reduction.dump(process_obj, to_child)
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingreduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle '_tkinter.tkapp' object
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingspawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "C:UsersAppDataLocalProgramsPythonPython38-32libmultiprocessingspawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

有人能说出我到底哪里出错了吗?

错误告诉您不能对包含tkinter小部件的对象使用多处理。您正试图在单独的进程中使用self.recvData。这需要对self进行酸洗,以便将其发送到其他进程。然而,python不能做到这一点,因为它包含无法腌制的tkinter小部件。

您需要将在另一个进程中运行的代码移动到一个不包含任何tkinter小部件的单独类中。

创建新类后更改的代码:

import socket
import turtle
# import timeit
import queue
import multiprocessing
from tkinter import *

class GUI:
def __init__(self, master):
self.master = master
master.title("Collision Detection")
self.input_label = Label(root, text="Input all the gratings set straight wavelength values in nm")
self.input_label.grid(row=0)
self.core_string = "Core "
self.entries = []

self.label_col_inc = 0
self.entry_col_inc = 1
self.core_range = range(1, 5)
for y in self.core_range:
self.core_text = self.core_string + str(y) + '_' + '25'
self.core_label = Label(root, text=self.core_text)
self.entry = Entry(root)
self.core_label.grid(row=1, column=self.label_col_inc, sticky=E)
self.entry.grid(row=1, column=self.entry_col_inc)
self.entries.append(self.entry)
self.label_col_inc += 2
self.entry_col_inc += 2
self.threshold_label = Label(root, text="Threshold in nm")
self.entry_threshold = Entry(root)
self.threshold_label.grid(row=2, sticky=E)
self.entry_threshold.grid(row=2, column=1)
self.light_label = Label(root, text='Status')
self.light_label.grid(row=3, column=3)
self.canvas = Canvas(root, width=150, height=50)
self.canvas.grid(row=4, column=3)
# Green light
self.green_light = turtle.RawTurtle(self.canvas)
self.green_light.shape('circle')
self.green_light.color('grey')
self.green_light.penup()
self.green_light.goto(0, 0)
# Red light
self.red_light = turtle.RawTurtle(self.canvas)
self.red_light.shape('circle')
self.red_light.color('grey')
self.red_light.penup()
self.red_light.goto(40, 0)
self.data_button = Button(root, text="Get data above threshold", command=recv_data.getData)
self.data_button.grid(row=5, column=0)

class recv_data:
def __init__(self):
self.buff_data = queue.Queue()
self.p1 = multiprocessing.Process(target=self.recvData)
self.p1 = multiprocessing.Process(target=self.calculate_threshold)
self.host = '127.0.0.1'
self.port = 5002
self.s = socket.socket()
self.s.connect((self.host, self.port))
# function to receive TCP data blocks
def getData(self):
len_message = self.s.recv(4)
bytes_length = int(len_message.decode('utf-8'))  # for the self-made server
recvd_data = self.s.recv(bytes_length)
self.buff_data.put(recvd_data)
self.p1.start()
self.p2.start()
self.p1.join()
self.p2.join()
def recvData(self):
len_message = self.s.recv(4)
while len_message:
bytes_length = int(len_message.decode('utf-8'))  # for the self-made server
recvd_data = self.s.recv(bytes_length)
self.buff_data.put(recvd_data)
len_message = self.s.recv(4)
else:
print('out of loop')
self.s.close()
def calculate_threshold(self):
rmv_data = self.buff_data.get()
stringdata = rmv_data.decode('utf-8')
rep_str = stringdata.replace(",", ".")
splitstr = rep_str.split()
# received wavelength values
inc = 34
wav_threshold = []
for y in gui.entries:
straight_wav = float(y.get())
wav = float(splitstr[inc])
wav_diff = wav - straight_wav
if wav_diff < 0:
wav_diff = wav_diff * (-1)
wav_threshold.append(wav_diff)
inc += 56
threshold = float(gui.entry_threshold.get())
# writing into the file
data = []
inc1 = 0
col1 = 2
col2 = 6
data.insert(0, (str(splitstr[0])))
data.insert(1, (str(splitstr[1])))
for x in wav_threshold:
if (x > threshold):
gui.red_light.color('red')
gui.green_light.color('grey')
data.insert(col1, (str(splitstr[34 + inc1])))
data.insert(col2, (str(x)))
else:
gui.red_light.color('grey')
gui.green_light.color('green')
data.insert(col1, '-')
data.insert(col2, '-')
inc1 += 56
col1 += 1
col2 += 1
self.write_file(data)
# function to write into the file
def write_file(self, data):
with open("Output.txt", "a") as text_file:
text_file.write('t'.join(data[0:]))
text_file.write('n')
if __name__ == '__main__':
root = Tk()
gui1 = GUI(root)
rec_data = recv_data()
root.mainloop()

我得到的错误:


Exception in Tkinter callback
Traceback (most recent call last):
File "C:UsersAppDataLocalProgramsPythonPython38-32libtkinter__init__.py", line 1883, in __call__
return self.func(*args)
TypeError: getData() missing 1 required positional argument: 'self'

相关内容

  • 没有找到相关文章