Skip to content
Advertisement

Issue when importing kivy.core.window and using the multiprocessing library

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:

enter image description here

Result when adding said library:

enter image description here

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()
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement