通过流程

时间:2015-11-24 14:20:57

标签: python class process tkinter

经过多年的阅读,这是我第一篇发表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()

2 个答案:

答案 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()