Kivy and multiprocessing

2,036 views
Skip to first unread message

Damien Frikha

unread,
Jul 23, 2014, 5:49:57 PM7/23/14
to kivy-...@googlegroups.com
Hi,

I'm using the Python multiprocessing library inside my Kivy app, and it works nicely.

My problem is that when I spawn a new process (can't fork on Windows), it opens a new (empty) Kivy window. I've tried everything I could think of, but in every case it still opens the window.

Does anyone know a workaround around this ?

I'm using Python 3.4/Kivy 1.8. Some time ago I had a 2.7/1.7 install on which I managed to do that, by importing kivy.window after starting the process. Tried it again to no avail.

Thanks.

ZenCODE

unread,
Jul 24, 2014, 2:08:22 AM7/24/14
to kivy-...@googlegroups.com
You could try spawning a service. I'm not sure about Android, but i know multi-proccessing is not currently supported for iOS.

Otherwise, iut it seems like it's working, just requiring a window for each one, consistent with the "one window per app" kivy approach. You might be able to dig into the code and see if there is an easy switch for this. For example, there is an environment variable that tells kivy to ignore some window stuff, used for building docs?

    if 'KIVY_DOC' in os.environ:
        return

Damien Frikha

unread,
Jul 24, 2014, 12:24:07 PM7/24/14
to kivy-...@googlegroups.com
I'm on Windows and only targeting Windows so I don't need my solution to be multi-platform.

I just ran some tests, it looks like Kivy opens a window as soon as the interpreter reads a kivy class call.

For instance, this:
from kivy.uix.widget import Widget
    class MyWidget(Widget):
        pass
Does not open a window when launched with Kivy (this code doesn't do anything I am fully aware of that)

But this:
from kivy.uix.widget import Widget
    class MyWidget(Widget):
        Widget()

Opens a window.

It's not even related with the App or Window class since I don't even import them in the project.
Launching widget.py (from the libraries) does not open a window either.

The question is, is it possible to change this behavior, and can I do that when spawning a new process?

ZenCODE

unread,
Jul 24, 2014, 2:16:22 PM7/24/14
to kivy-...@googlegroups.com
From what you say, it seems like you can just avoid creating any uix widgets? They probably import the core window which creates the window you see. Let's look.


from kivy.uix.widget import Widget
    class MyWidget(Widget):
        pass

Yes, that does not open a window because nowhere is a widget created, just defined. Hence no window.


from kivy.uix.widget import Widget
    class MyWidget(Widget):
        Widget()

Okay, now you are creating a widget, thus the Window. The brackets create instances if they follow a class name.

"It's not even related with the App or Window class since I don't even import them in the project."

Widgets are visual and part of the kivy uix, and thus relate to and import core window stuff.

"Launching widget.py (from the libraries) does not open a window either."

Probably because it does not instantiate any  Widget, it just defines what a Widget is. So I hope that clarifies?

Peace out


Damien Frikha

unread,
Jul 24, 2014, 4:03:49 PM7/24/14
to kivy-...@googlegroups.com
Yeah, you basically summed up what I came to understand from these tests. But, since I didn't instantiate the "MyWidget" class in my code (it's just a class definition), the Widget() call shouldn't be made too, should it? Meaning that the core window stuff shouldn't be added, thus creating the window?

The problem is that it did, so I don't see how I could spawn a new process from the main code without opening a new window, since whatever I do there will always be somewhere in a class definiton where I instantiate a kivy class.

Brendon Higgins

unread,
Jul 24, 2014, 4:38:36 PM7/24/14
to kivy-...@googlegroups.com
I might be wrong, but instantiating an unnamed *class variable* doesn't sound
like standard usage to me. Even if you gave that class variable a name (e.g.
"w = Widget()"), having a widget in a class variable sounds like something is
wrong. Surely widgets should (almost?) always be instance variables, in which
case they shouldn't be created (and a window shouldn't appear) unless you make
an instance of your class. Are you forgetting a "def __init__(self):" to define
the class constructor before instantiating a widget in that?

Peace,
Brendon

On July 24, 2014 13:03:49 Damien Frikha wrote:
> Yeah, you basically summed up what I came to understand from these tests.
> But, since I didn't instantiate the "MyWidget" class in my code (it's just
> a class definition), the Widget() call shouldn't be made too, should it?
> Meaning that the core window stuff shouldn't be added, thus creating the
> window?
>
> The problem is that it did, so I don't see how I could spawn a new process
> from the main code without opening a new window, since whatever I do there
> will always be somewhere in a class definiton where I instantiate a kivy
> class.
>
> Le jeudi 24 juillet 2014 11:16:22 UTC-7, ZenCODE a écrit :
> > From what you say, it seems like you can just avoid creating any uix
> > widgets? They probably import the core window which creates the window you
> > see. Let's look.
> >
> > from kivy.uix.widget import Widget
> >
> > class MyWidget(Widget):
> > pass
> >
> > Yes, that does not open a window because nowhere is a widget created, just
> > defined. Hence no window.
> >
> > from kivy.uix.widget import Widget
> >
> > class MyWidget(Widget):
> > Widget()
> >
> > Okay, now you are creating a widget, thus the Window. The brackets create
> > instances if they follow a class name.
> >
> > *"It's not even related with the App or Window class since I don't even
> > import them in the project."*
> >
> > Widgets are visual and part of the kivy uix, and thus relate to and import
> > core window stuff.
> >
> > *"Launching widget.py (from the libraries) does not open a window
> > either."*

ZenCODE

unread,
Jul 24, 2014, 5:15:44 PM7/24/14
to kivy-...@googlegroups.com, bre...@quantumfurball.net
@Damien


"But, since I didn't instantiate the "MyWidget" class in my code (it's just a class definition), the Widget() call shouldn't be made too, should it?"

You did not instantiate "MyWidget", but when you defined it, in that definition, you created an instance.

    class MyWidget(Widget):
        Widget()
   # Instantiated!

The "Widget()" is part of the class definition here, and class definitions are executed whenever python encounters them - after all it needs to know how to create a class when required. If you only want to create a widget on instantiation, you do this (as Brendon mentioned):

    class MyWidget(Widget):
        def __init__(self):
            super(MyWidget, self).__init__(**kwargs)
            self.widget = Widget()

Although this does not make much sense, as you're just attaching another instance of a widget to you subclass, so it's not exactly clear what you are trying to do?

@Brendon

Yeah, you're right,  and you almost always want widgets to be instance bound. Generally, you only attach primitives to the "class definitions" to serve as default values inherited by instances.e.g.

    class Bob(object):
        surname = "Knob"

Any class subclassing that will inherit that "Knob", so it's a convenient and efficient way to share properties between subclasses. Interestingly, kivy properties are instantiated and attached to class definitions.

    class SillyTest(Widget):
        walk = StringProperty("very")

But this is done so properties can all the binding, callbacks and and property events that make us love kivy so much ;-) So, there are always cases where generalizations don't apply I suppose...

Cheers

Damien Frikha

unread,
Jul 24, 2014, 5:30:22 PM7/24/14
to kivy-...@googlegroups.com, bre...@quantumfurball.net
Yeah yeah yeah this is it! I had somewhere in my code some widgets defined as class variables, and they were responsible for the window to open.

The window doesn't open anymore when I spawn a new process, this is exactly what I wanted.

Thank you both!
Reply all
Reply to author
Forward
0 new messages