python - Nested / alternating apps with Kivy -
i'd have kivy app function launcher other kivy apps, depending on input. way implemented below not working (because kv
file gets reloaded , styles reapplied, adding more , more buttons), , there seems recursion trace suggests when hit esc
exit.
i warning app1.kv
loaded multiple times, however, in documentation app.load_kv()
says
this method invoked first time app being run if no widget tree has been constructed before app.
this implies me should possible run()
app multiple times?
here code:
main.py
from kivy.uix.widget import widget kivy.uix.gridlayout import gridlayout kivy.app import app kivy.properties import objectproperty kivy.uix.button import button kivy.clock import clock kivy.logger import logger 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("<sequencesgame@gridlayout>:\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 <sequencesgame@gridlayout>: cols: 2 button: text: "hello 111" sequencesgame:
this seems issue if apps not nested:
main2.py
from kivy.app import app kivy.clock import clock kivy.logger import logger kivy.lang import builder class app1(app): pass class app2(app): def build(self): return builder.load_string("<sequencesgame@gridlayout>:\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()
in end followed @inclement's suggestion of using multiprocessing
. here basic implementation (without communication through pipes or queues):
import sys import multiprocessing kivy.app import app kivy.lang import builder 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 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' self.next_app] if __name__ == '__main__': counter = 0 w = wrapper() while true: counter += 1 print "started app instance {}".format(counter) w.swap() sleep(5)
Comments
Post a Comment