经过多年的阅读,这是我第一篇发表Stack Overflow的文章。
我正在编写Python程序并使用TKInter构建前端。我的班级里有一个名为label_cpu的标签。我希望我可以在进程中使用方法cpu_counter来更新当前CPU利用率时间的标签。如果我打电话给实例'方法,比如GUI.cpu_counter()标签更新,但是当我尝试通过process.start()启动方法时,它会出现以下消息:
Traceback (most recent call last):
File "C:/Users/Chris Local/OneDrive/Github/python/gui2.py", line 51, in <module>
p.start()
File "C:\Python35\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Python35\lib\multiprocessing\context.py", line 212, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Python35\lib\multiprocessing\context.py", line 313, in _Popen
return Popen(process_obj)
File "C:\Python35\lib\multiprocessing\popen_spawn_win32.py", line 66, in __init__
reduction.dump(process_obj, to_child)
File "C:\Python35\lib\multiprocessing\reduction.py", line 59, in dump
ForkingPickler(file, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <class '_tkinter.tkapp'>: attribute lookup tkapp on _tkinter failed
Process finished with exit code 1
以下代码:
from tkinter import *
import thread
import sys
import os
from multiprocessing import Process
from tkinter import Tk, Checkbutton, Label
from tkinter import StringVar, IntVar
class MainMenu:
def __init__(self, master):
frame = Frame(master)
frame.pack()
# Configure label for CPU counter/thread
self.m = StringVar()
self.m.set("CPU COUNTER GOES HERE")
self.label_cpu = Label(frame, textvariable = self.m)
self.button1 = Button(frame, text = "1. Enter Provinces (from Scratch)")
self.label_cpu.grid(row=1, sticky = W)
self.button1.grid(row=2, sticky = W)
def cpu_counter(self):
while (1 > 0):
v = str(os.times())
print(v)
self.m.set(v)
def cpu_counter_external(GUI):
#I tried tricking out the process.start() by aiming it here, but
#this doesn't work if launched in a process either.
GUI.cpu_counter()
if __name__ == '__main__':
root = Tk()
menubar = Menu(root)
menubar.option_add('*tearOff', FALSE)
submenu = Menu(menubar)
menubar.add_cascade(label = "File!", menu = submenu)
menubar.add_cascade(label = "Help!", menu = submenu)
root.config(menu=menubar)
GUI = MainMenu(root)
p = Process(target = GUI.cpu_counter)
#The following line, GUI.cpu_counter() updates the label
#but it should not be run unless in a process.
#GUI.cpu_counter()
p.start()
p.join()
root.mainloop()
答案 0 :(得分:1)
您不能以这种方式使用Tkinter进行多处理。无法在进程之间共享Tkinter对象。
答案 1 :(得分:0)
如果我了解您要执行的操作,则无需进行多处理。否则使用管理员字典,请参阅Doug Hellman的Pymotw https://pymotw.com/2/multiprocessing/communication.html以及网络上其他地方的Managng共享状态和共享命名空间。如果您想了解更多信息,请使用管理员字典重新发布新主题。
from tkinter import *
import thread
import sys
import os
from multiprocessing import Process
## redundant as you already have import *
##from tkinter import Tk, Checkbutton, Label
##from tkinter import StringVar, IntVar
class MainMenu:
def __init__(self, master):
self.master=master
frame = Frame(master)
frame.pack()
self.ctr=0
# Configure label for CPU counter/thread
self.m = StringVar()
self.m.set("CPU COUNTER GOES HERE")
self.label_cpu = Label(frame, textvariable = self.m)
self.button1 = Button(frame, text = "1. Enter Provinces (from Scratch)")
self.label_cpu.grid(row=1, sticky = W)
self.button1.grid(row=2, sticky = W)
self.cpu_counter()
def cpu_counter(self):
v = str(os.times())
print(v, self.ctr)
self.m.set(v)
if self.ctr < 100: ## stop while testing
self.ctr += 1
self.master.after(100, self.cpu_counter)
def cpu_counter_external(GUI):
#I tried tricking out the process.start() by aiming it here, but
#this doesn't work if launched in a process either.
GUI.cpu_counter()
if __name__ == '__main__':
root = Tk()
menubar = Menu(root)
menubar.option_add('*tearOff', FALSE)
submenu = Menu(menubar)
menubar.add_cascade(label = "File!", menu = submenu)
menubar.add_cascade(label = "Help!", menu = submenu)
root.config(menu=menubar)
GUI = MainMenu(root)
## p = Process(target = GUI.cpu_counter)
#The following line, GUI.cpu_counter() updates the label
#but it should not be run unless in a process.
#GUI.cpu_counter()
## p.start()
## p.join()
root.mainloop()