Python 2.7、多处理和 Tkinter [英] Python 2.7, Multiprocessing and Tkinter

查看:56
本文介绍了Python 2.7、多处理和 Tkinter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个类,该类使用多处理从新的 python 实例启动 tkinter 表单.

I am trying to create a class that launches a tkinter form from a new instance of python using multiprocessing.

我的问题是:将 Tkinter 类对象传递给多处理函数的推荐方法是什么?当我通常将对象传递给多处理池时,我必须将对象转换为字符串.这是否意味着我必须腌制课程?有没有更好的方法来做到这一点?

My question is this: What would be the recommended way of passing the Tkinter class object to the multiprocessing function? When I normally pass objects to the multiprocessing pool, I have to convert the objects to string. Does this mean I have to pickle the class? Is there a better way to do this?

我不能使用线程,因为我必须使用的一些 python 包不是线程安全的.. :(

I cannot using threading because some of the python packages I have to use are not thread safe.. :(

示例代码:

import Tkinter as Tk

########################################################################
class TkinterApp(object):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""

        self.root = parent
        self.root.title("Main frame")
        self.frame = Tk.Frame(parent)
        self.frame.pack()

        btn = Tk.Button(self.frame, text="Close Frame", command=self.hide)
        btn.pack()

    #----------------------------------------------------------------------
    def hide(self):
        """"""
        self.root.withdraw()

系统规格:

  • Windows 7
  • Python 2.7.5 32 位

非常欢迎任何建议或反馈!

Any suggestions or feedback is very welcome!

谢谢

推荐答案

在池外创建 Tkinter 实例以及类实例,然后从不同的进程调用函数时,我没有遇到任何问题.下面是一个简单"的例子

I haven't encountered any problems creating the Tkinter instance outside of the pool, and the class instance as well, and then calling the functions from separate processes. A "simple" example is below

from multiprocessing import Process
import time

try:
    import Tkinter as tk    ## Python 2.x
except:
    import tkinter as tk    ## Python 3.x

class ProgressBar():
    def __init__(self, root):
        self.root=root
        self.root.geometry("75x50+900+100")
        self.ctr=25

    def mainloop(self):
        self.root.mainloop()

    def start_countdown(self):
        """ a separate process in a separate GUI
        """
        self.root.withdraw()
        self.top_count=tk.Toplevel(self.root)
        self.top_count.geometry("75x50+750+50")
        self.label_ctr = tk.IntVar()
        self.label_ctr.set(self.ctr)
        label = tk.Label(self.top_count, textvariable=self.label_ctr)
        label.pack()
        if self.ctr > 0:
            self.top_count.after(750, self.update)

    def start_running(self):
        """ create the progress bar widget
        """
        self.top=tk.Toplevel(self.root, takefocus=True)
        self.top.title("Progress Bar")
        self.top.geometry("+700+200")
        canvas = tk.Canvas(self.top, width=261, height=60, bg='lightgray')
        canvas.pack()

        rc2 = canvas.create_rectangle(15, 20, 243, 50, outline='blue', \
                                      fill='lightblue')
        rc1 = canvas.create_rectangle(24, 20, 34, 50, outline='white', \
                                      fill='blue')

        total=100
        x = 5
        while self.ctr:        ## move the small rectangle +5 or -5 units
            total += x
            if total > 311:
                x = -5
            elif total < 100:
                x = 5
            time.sleep(0.2)
            canvas.move(rc1, x, 0)
            canvas.update()

    def update(self):
        self.ctr -= 1
        self.label_ctr.set(self.ctr)

        if self.ctr > 0:
            self.top_count.after(750, self.update)
        else:
            ## sleep to allow any remaining after() to execute
            ## can also use self.root.after_cancel(id)
            self.top_count.after(500, self.root.destroy) ## destroy root when zero is reached

root = tk.Tk()

PB=ProgressBar(root)
pr1=Process(target=PB.start_countdown(), args=())
pr1.start()

pr2=Process(target=PB.start_running(), args=())
pr2.start()

## start mainloop in a separate process as a function of the class
## don't know if this is really necessary or not
## the theory is, it is detached from the other 2 processes and so
##    can react to both independently
## also the mainloop() process can be killed=shut down properly
pr3=Process(target=PB.mainloop(), args=())
pr3.start()

## safety clean up
pr1.terminate()
pr2.terminate()
pr3.terminate()

这篇关于Python 2.7、多处理和 Tkinter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆