First of all, I’d like to clarify that I have absolutely 0 background as a software engineer and this is the first time I’m using python for something besides API’s and creating excel/plots.
My issue is that I was trying to create an app using kivy and then I imported the kivy.core.window
library a blank screen appears.
I’ve seen that this issue is fairly common when using kivy and multiprocessing, but none of the information I found fixed my problem. Result of running my code without the kivy.core.window
library:
Result when adding said library:
Also, if I wait like 10 seconds the blank screen disappears and kills the count_time process.
from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition import time from datetime import datetime import multiprocessing as mp from multiprocessing import Process, Queue, freeze_support Builder.load_string(''' <TestScreen>: BoxLayout: orientation: "vertical" # place object vertically Label: size_hint: 1, 1 text: 'TITLE' font_size: 150 color: 1, 1, 1, 1 Button: text: 'start' on_press: root.start_mp() Button: text: 'stop' on_press: root.stop_time() ''') def count_time(x): for i in range(x): print('count={}'.format(i)) time.sleep(1) class Test(App): def build(self): sm.add_widget(TestScreen(name='test')) return sm class TestScreen(Screen): def __init__(self, **kwargs): super(TestScreen, self).__init__(**kwargs) def start_mp(self): self.p1 = mp.Process(target=count_time, args=(10, )) self.p1.start() def stop_time(self): pass if __name__ == '__main__': mp.freeze_support() sm = ScreenManager(transition=NoTransition()) Test().run()
Advertisement
Answer
The problem is that when you run Process
, it starts a new python proces and imports the current .py
file. On most platforms, the line:
if __name__ == '__main__':
protects the Test().run()
from being executed and starting another App
and is enough to protect from another window being opened. However, it appears that importing kivy.core.window
is enough to open another window (on Windows platform) when the original .py
file is imported for multiprocessing. You can read about it here.
A really ugly work around is to protect all kivy imports (and as a result, all the kivy code) with a if __name__ == '__main__':
line. Like this:
import time import multiprocessing as mp def count_time(x): for i in range(x): print('count={}'.format(i)) time.sleep(1) if __name__ == '__main__': mp.freeze_support() from kivy.core.window import Window from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition Builder.load_string(''' <TestScreen>: BoxLayout: orientation: "vertical" # place object vertically Label: size_hint: 1, 1 text: 'TITLE' font_size: 150 color: 1, 1, 1, 1 Button: text: 'start' on_press: root.start_mp() Button: text: 'stop' on_press: root.stop_time() ''') class Test(App): def build(self): sm = ScreenManager(transition=NoTransition()) sm.add_widget(TestScreen(name='test')) return sm class TestScreen(Screen): def __init__(self, **kwargs): super(TestScreen, self).__init__(**kwargs) def start_mp(self): self.p1 = mp.Process(target=count_time, args=(10,)) self.p1.start() def stop_time(self): pass Test().run()