【发布时间】:2016-03-15 03:25:04
【问题描述】:
我是 Kivy 和多处理的新手。
我正在探索同时运行多个 Kivy 应用程序,使用多处理,方式与以下相同:Running multiple Kivy apps at same time that communicate with each other。
现在,我想维护当前运行的应用程序的共享列表,例如 Manager.list(),但我一开始就卡住了。我有一个这样的测试代码:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from multiprocessing import Process, Manager
class ParentApp(App):
def __init__(self, app_list, **kwargs):
super(ParentApp, self).__init__(**kwargs)
self.app_list = app_list
def build(self):
self.add_self_to_list()
return Label(text = "abc")
# def on_start(self):
# self.add_self_to_list()
def add_self_to_list(self):
self.app_list.append(self)
if __name__ == "__main__":
manager = Manager()
my_list = manager.list()
print "Before:"
print my_list
parent = ParentApp(my_list)
p = Process(target = parent.run)
p.start()
p.join()
print "After:"
print my_list
这会将ParentApp 正确添加到共享的my_list,但是当我在build 中注释掉self.add_self_to_list() 并取消注释on_start 时,我得到了这个PicklingError:
...
self.app_list.append(self)
File "<string>", line 2, in append
File "C:\Kivy-1.9.0-py2.7-win32-x64\Python27\lib\multiprocessing\managers.py", line 758, in _callmethod
conn.send((self._id, methodname, args, kwds))
PicklingError: Can't pickle <type 'code'>: attribute lookup __builtin__.code failed
我还尝试将add_self_to_list 挂钩到按钮的on_press 回调,但我得到了同样的错误。为什么它适用于 build 方法而不适用于回调?有没有办法解决这个问题?
我在 Windows 7 上运行 Kivy 1.9.0 和 Python 2.7。
(如果您想知道我为什么要这样尝试:每个应用程序都可能调用其他应用程序。如果一个应用程序已经在运行,我不想启动一个新应用程序并用副本污染屏幕同一个窗口。理想情况下,我会抓住应用程序并在前面弹出它的窗口。我还没有尝试过 Kivy 应用程序的 root_window,所以我什至不确定这是否可能。只是查看选项在这里 :) 如果您已经知道这是否可以使用 Kivy 完成,我也想知道,但也许我会发布另一个问题! )
【问题讨论】:
标签: python user-interface kivy pickle python-multiprocessing