具有多处理的Tkinter:OSError[Errno 22]参数无效

2024-09-30 04:29:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试将多处理添加到我的tkinter应用程序中,但我遇到了错误:TypeError: cannot pickle '_tkinter.tkapp' object。我看了一下question here中提出的解决方案,并尝试实现我自己的版本,这似乎解决了这个特定错误,但现在我改为使用常量OSError: [Errno 22] Invalid argument:

我希望代码能够在后台执行一些计算,并将计算结果放入队列(此处仅为整数,但在实际代码中为Numpy数组)。然后,GUI应用程序向用户显示一些统计信息和结果

from multiprocessing import Process, Queue
from queue import Empty
import tkinter as tk
from tkinter import Tk

class FooUI(Process):
    def __init__(self, q: Queue):
        super().__init__(target=self, args=(q,))
        self.queue = q
        self.duh = []
        self.root = Tk()
        self._create_interface()
        self.root.after(100, self._check_queue)
        self.root.mainloop()
        
    def _check_queue(self):
        try:
            out = self.queue.get_nowait()
            if out:
                self.duh.append(out)
                print(self.duh)
                return
        except Empty:
            pass
        self.root.after(100, self._check_queue) 
    
    def _create_interface(self):
        self.root.geometry("100x100")
        b = tk.Button(self.root, text='Start', command=self.calc)
        b.grid(row=0, column=0)
    
    def calc(self):
        p = Process(target=do_calc)
        p.start()     
        
def do_calc(q: Queue):
    for i in range(20):
        q.put(i**2)


If __name__ == '__main__':
    q = Queue()
    f = FooUI(q)
    f.start()

这是回溯:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 125, in _main
    prepare(preparation_data)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 264, in run_path
    code, fname = _get_code_from_file(run_name, path_name)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 234, in _get_code_from_file
    with io.open_code(decoded_path) as f:
OSError: [Errno 22] Invalid argument: 'C:\\python\\block_model_variable_imputer\\<input>'
Traceback (most recent call last):
  File "<input>", line 3, in <module>
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\reduction.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:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 125, in _main
    prepare(preparation_data)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 264, in run_path
    code, fname = _get_code_from_file(run_name, path_name)
  File "C:\Users\cherp2\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 234, in _get_code_from_file
    with io.open_code(decoded_path) as f:
OSError: [Errno 22] Invalid argument: 'C:\\python\\block_model_variable_imputer\\<input>'

我已经试了一段时间让它工作。任何帮助都将不胜感激


Tags: pathinpyselfmainliblocalline
1条回答
网友
1楼 · 发布于 2024-09-30 04:29:39

您以错误的方式创建了Process()的子类。您需要重写run()方法,而不是传递target选项

from multiprocessing import Process, Queue
from queue import Empty
import tkinter as tk

class FooUI(Process):
    def __init__(self, q: Queue):
        super().__init__() # don't pass target and args options
        self.queue = q
        self.duh = []
    
    # override run() method and create the Tk() inside the function
    def run(self):
        self.root = tk.Tk()
        self._create_interface()
        self.root.after(100, self._check_queue)
        self.root.mainloop()
        
    def _check_queue(self):
        try:
            out = self.queue.get_nowait()
            if out:
                self.duh.append(out)
                print(self.duh)
                #return
        except Empty:
            pass
        self.root.after(100, self._check_queue) 
    
    def _create_interface(self):
        self.root.geometry("100x100")
        b = tk.Button(self.root, text='Start', command=self.calc)
        b.grid(row=0, column=0)
    
    def calc(self):
        if self.queue.empty():
            self.duh.clear()
            p = Process(target=do_calc, args=[self.queue]) # pass self.queue to do_calc()
            p.start()     
        
def do_calc(q: Queue):
    for i in range(20):
        q.put(i**2)

if __name__ == '__main__':
    q = Queue()
    f = FooUI(q)
    f.start()

相关问题 更多 >

    热门问题