2016-01-21 84 views
0

我希望将kivy应用程序的功能作为其他kivy应用程序的启动程序,具体取决于输入。我在下面实现它的方式显然不起作用(因为kv文件被重新加载并重新应用它的样式,因此增加了越来越多的按钮),并且当我点击Esc退出时跟踪建议似乎也有一些递归。与Kivy嵌套/交互应用程序

我得到的是app1.kv然而加载多次,在文档中的App.load_kv()警告它说

调用此方法的第一次,如果没有 widget树一直是应用程序正在运行为此应用程序构建之前。

这意味着我应该可以对run()一个应用程序多次?

这里是我的代码:

main.py

from kivy.uix.widget import Widget 
from kivy.uix.gridlayout import GridLayout 
from kivy.app import App 
from kivy.properties import ObjectProperty 
from kivy.uix.button import Button 
from kivy.clock import Clock 
from kivy.logger import Logger 
from kivy.lang import Builder 

class OutsideApp(App): 
    current_app = ObjectProperty(None) 

    def build(self): 
     Clock.schedule_interval(self.update, 3) 
     return Widget() 

    def update(self, dt): 
     if isinstance(self.current_app, App): 
      self.current_app.stop() 
     if isinstance(self.current_app, App1): 
      self.current_app = App2() 
     else: 
      self.current_app = App1() 
     self.current_app.run() 

class App1(App): 
    pass 
class App2(App): 
    def build(self): 
     gl = Builder.load_string("<[email protected]>:\n cols: 2\n Button:\n  text: \"hello 2\"\nSequencesGame:") 
     return gl 

if __name__ == '__main__': 
    oa = OutsideApp() 
    oa.run() 

app1.kv

#:kivy 1.0.9 
<[email protected]>: 
    cols: 2 
    Button: 
     text: "hello 111" 
SequencesGame: 

这似乎是即使应用程序没有嵌套的问题:

main2.py

from kivy.app import App 

from kivy.clock import Clock 
from kivy.logger import Logger 
from kivy.lang import Builder 

class App1(App): 
    pass 
class App2(App): 
    def build(self): 
     return Builder.load_string("<[email protected]>:\n cols: 2\n Button:\n  text: \"hello 2\"\nSequencesGame:") 

current_app = None 

def switch(*args): 
    global current_app 
    if isinstance(current_app, App): 
     current_app.stop() 
    if isinstance(current_app, App1): 
     current_app = App2() 
    else: 
     current_app = App1() 
    current_app.run() 

if __name__ == '__main__': 
    Clock.schedule_interval(switch, 2) 
    switch() 
+0

你就不能有一个应用程序与下屏幕管理多个屏幕,每个屏幕,,另一个应用程序'? – jligeza

+0

我想重复使用现有的应用程序。此外,像配置文件似乎很好地封装在应用程序级别。 – zeeMonkeez

+1

为什么不在其他子程序中运行其他应用程序? – inclement

回答

0

最后,我跟着@使用multiprocessing的恶劣的建议。这是一个基本的实现(不通过通信管道或队列):

import sys 
import multiprocessing 
from kivy.app import App 
from kivy.lang import Builder 
from time import sleep#, localtime, time 

def str_to_class(str): 
    return reduce(getattr, str.split("."), sys.modules[__name__]) 

class App1(App): 
    def build(self): 
     return Builder.load_string("BoxLayout:\n Button:\n  text: \"hello 1\"") 

class App2(App): 
    def build(self): 
     return Builder.load_string("BoxLayout:\n Button:\n  text: \"hello 2\"") 


class Wrapper(object): 
    def __init__(self, *kargs, **kwargs): 
     super(Wrapper, self).__init__() 
     self.running_app = None 
     self.next_app = 'App1' 

    def change_running_app(self, name='App1'): 
     if self.running_app is not None: 
      self.running_app.terminate() 
     self.running_app = multiprocessing.Process(target=self.run_app, kwargs={'name':name}) 
     self.running_app.start() 

    def run_app(self, name='App1'): 
     app = str_to_class(name)() 
     app.run() 

    def swap(self): 
     self.change_running_app(name=self.next_app) 
     self.next_app = ['App1', 'App2']['App1' is self.next_app] 

if __name__ == '__main__': 
    counter = 0 
    w = Wrapper() 
    while True: 
     counter += 1 
     print "Started App instance {}".format(counter) 
     w.swap() 
     sleep(5)