Вот еще один возможный ответ:
import time
from functools import partial
from threading import Thread
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
import io
from contextlib import redirect_stdout
from myscript import printing
class MyLayout(BoxLayout):
run_script = False
def run_script_in_thread(self):
self.the_thread = Thread(target=self.script, daemon=True).start()
def script(self):
self.run_script = True
f = io.StringIO()
with redirect_stdout(f):
while self.run_script:
time.sleep(1)
printing()
out = f.getvalue()
Clock.schedule_once(partial(self.set_label, out), -1)
def set_label(self, value, dt):
self.ids.the_output.text = value
def stop_script(self):
self.run_script = False
theRoot = Builder.load_string('''
MyLayout:
orientation: 'horizontal'
Label:
id: the_output
Button:
text: 'Start'
on_release: root.run_script_in_thread()
Button:
text: 'Stop'
on_release: root.stop_script()
''')
class MyApp(App):
def build(self):
return theRoot
if __name__ == '__main__':
MyApp().run()
Используется redirect_stdout
для захвата вывода из printing()
, который импортируется с использованием from myscript import printing
. Обратите внимание, что ваш while
цикл не может быть использован, потому что он защищен if __name__ == "__main__":
.
Если вам нужно запустить скрипт, включая цикл while
, вы можете использовать отдельный Process
для его запуска и Pipe
для захвата вывода.