应用程序用于存储和查看多个实例
我的这个基于Toga的应用程序让用户在一系列框里输入信息。最后,这些信息会用来启动一些由调度器管理的进程。一旦这些进程启动,应用程序就会通过不断更新状态框来向用户显示进度。
用户可以同时运行多个应用程序实例。用户应该能够创建一个新的应用实例,并查看所有正在进行的实例的状态框。
目前的做法是使用了multiprocessing
来提高操作的稳定性,基本上是这样的:
import toga
import multiprocessing
from toga.style import Pack
class Test(toga.App):
instances = []
def startup(self):
self.main_box = toga.Box(style=Pack(direction='column'))
self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = self.main_box
self.main_window.show()
self.work()
def work(self):
add_but = toga.Button('Add instance to list', on_press=self.add_but_hdl)
ins_num = len(Test.instances) + 1
ins_lbl = toga.Label('Current instance number is {}'.format(ins_num))
if Test.instances:
prv_ins_idx = len(Test.instances) - 1
self.main_box.add(Test.instances[prv_ins_idx].main_window.show(),
ins_lbl,
add_but)
else:
self.main_box.add(ins_lbl, add_but)
def add_but_hdl(self, widget):
Test.instances.append(self)
self.init_proc()
def init_proc(self):
proc = multiprocessing.Process(target=self.mk_app_ins)
proc.start()
def mk_app_ins(self):
new_ins = Test()
new_ins.main_loop()
def main():
return Test()
当通过briefcase dev
运行上述代码,并点击将实例添加到列表时,会出现以下错误:
[tender] 正在以开发模式启动... =========================================================================== 注册失败:接口org.gtk.Application已经有一个对象被导出在...
这个设置能否正常工作,还是应该放弃,换一种完全不同的方法?可行的解决方案可能是什么样的呢?
1 个回答
1
根据multiprocessing
的文档,在Linux系统上,默认的进程启动方式是fork
。这意味着“子进程一开始就和父进程几乎一模一样”。所以,子进程会认为它已经有一个图形界面在运行了。
因此,你可能应该使用spawn
方法,这样子进程就能从头开始。你可以通过调用multiprocessing.set_start_method
来实现。
或者,与其处理多个进程的复杂性,不如只用一个进程来创建多个窗口,这样可能更简单。Toga在Linux、Windows和macOS上都支持这个功能。
在Android或iOS上,Toga目前只支持一个窗口,但你可以随意修改这个窗口的用户界面,让用户看到不同的内容。你可以通过添加或移除子组件,甚至重新设置窗口的content
属性来做到这一点。