Google Analytics

Wednesday, May 7, 2014

Learning Kivy - Part 1

Prev

Table of Contents


  • Learning Kivy - Part 1
  • Learning Kivy - Part 2
  • Learning Kivy - Part 3
  • Learning Kivy - Part 4
  • Learning Kivy - Part 5
  • Learning Kivy - Part 6

  • Kivy provides a GUI interface.  It provides Python programmers with a method to present a Graphical User Interface.  More at kivy.org

    I'm learning Kivy, and frankly, am struggling with it.  While I have an extensive programming background, almost none of that experience is associated with GUI programming.  Kivy, being new, has very doesn't have as much documentation available for it as does other GUI tools, such as TkInter.  So I thought, if I was struggling, my movement through the learning process might be of interest to others....so here we are!  (BTW - here's a link to an excellent series of articles by Dusty Phillips.  Dusty also has a book out on Kivy, which I've found very useful, but a little more advanced than where I'm at today, thus my need to experiment.)

    Dusty's site has a good approach, where he places a 'Table of Contents' with links on each page.  I'm going to duplicate that approach, as one of the issues with having a blog is it isn't very easy to pull articles together to make a coherent package...this will help.

    In the early parts, I'm going to be treating really basic stuff.  However, I'm not going to be treating setup, installation and running of Kivy nor Python.  Dusty's site, and kivy.org, should be consulted.

    Kivy typically has two components: a Python program portion, with a file extension of .py, and a Kivy Language portion, with a file extension of .kv

    Suggested approaches are to put the programming logic into the Python portion, and the Kivy Language portion in the Kivy .kv file.

    While it's possible to just do everything from Python, and not have a Kivy Language .kv file, I'm not going to take that approach - I'll be developing correlated .py and .kv files for each project.

    Simple Insight for this page:
    • There must be a Python class in the .py file that extends App.  This means App must be previously defined, and it is; it's in kivy.app.  To get this into the Python page, it must be imported, via this command:
      • from kivy.app import App
    • The example class I'm going to build is Simple.  So the Python statement for the class is:
      • class Simple(App):
    • This Simple class must define a method, build.  Here's the build method:
      • def build(self):
    Together, so far, we have:

    class Simple(App):
        def build(self):


    Per Kivy, the build method has to return something - an instance of the class that's being created in the .kv file.  So, even though I haven't yet created the .kv file, I'm going to have the build method return an instance of Box_a.  I'm doing things a little bit differently than you might find in other examples, but I'm doing this because I wanted to point out some differences.  Most articles aimed at learning Kivy will have you using the Simple class for everything, but here I'm not - I'm using the Simple.py, the simple.kv, but a Box_a class.

    If you know Python, you also know that the Box_a instance must be a class, and therefore this class must be defined.  So the next code snippet will have the Box_a class defined, and instantiated and returned in the build method.

    The snippet will also include a main method to invoke everything (you should be familiar with this from common Python programming).  Within this main method, it will create an instance of the Simple class placed into s, and then run it via a call to s.run().

    I'm also going to put a couple of print statements into the code, so you can see (when you execute your program) where these calls are made, because you don't actually call the Simple.build() method anywhere!  Kivy does that.

    Note one more thing: class Box_a is going to extend BoxLayout which means we've got to import it too.

    So here's a complete listing, including the required import statements:

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout

    class Box_a(BoxLayout):
        print("Box_a entry")

    class Simple(App):
        def build(self):
            print("inside build")
            return Box_a()

    def main():
        s = Simple()
        s.run()

    if __name__ == '__main__':
        main()

    When you run this Python program, you should get a terminal window (aka console window) with information from Kivy, then a blank popup window.   If you look at the terminal window carefully, you should see something similar to this (be sure and look for the 'Box_a entry' and 'inside build' printouts within that output - I've highlighted below, but your system won't do this):

    [INFO   ] Kivy v1.7.2
    [INFO   ] [Logger      ] Record log in /home/superben/.kivy/logs/kivy_14-05-07_56.txt
    [INFO   ] [Factory     ] 144 symbols loaded
    [DEBUG  ] [Cache       ] register with limit=None, timeout=Nones
    [DEBUG  ] [Cache       ] register with limit=None, timeout=60s
    [DEBUG  ] [Cache       ] register with limit=None, timeout=Nones
    [INFO   ] [Image       ] Providers: img_tex, img_dds, img_pygame, img_pil, img_gif 
    [DEBUG  ] [Cache       ] register with limit=1000, timeout=60s
    [DEBUG  ] [Cache       ] register with limit=1000, timeout=3600s
    Box_a entry
    [DEBUG  ] [App         ] Loading kv <./simple.kv>
    inside build
    [DEBUG  ] [Window      ] Ignored (import error)
    [INFO   ] [Window      ] Provider: pygame(['window_egl_rpi'] ignored)
    [DEBUG  ] [Window      ] Display driver x11
    [DEBUG  ] [Window      ] Actual window size: 800x600
    [DEBUG  ] [Window      ] Actual color bits r8 g8 b8 a0
    [DEBUG  ] [Window      ] Actual depth bits: 24
    [DEBUG  ] [Window      ] Actual stencil bits: 8
    [DEBUG  ] [Window      ] Actual multisampling samples: 2
    [INFO   ] [GL          ] OpenGL version <4 .4.0="" 331.20="" nvidia="">
    [INFO   ] [GL          ] OpenGL vendor
    [INFO   ] [GL          ] OpenGL renderer
    [INFO   ] [GL          ] OpenGL parsed version: 4, 4
    [INFO   ] [GL          ] Shading version <4 .40="" cg="" compiler="" nvidia="" via="">
    [INFO   ] [GL          ] Texture max size <16384>
    [INFO   ] [GL          ] Texture max units <32>
    [DEBUG  ] [Shader      ] Fragment compiled successfully
    [DEBUG  ] [Shader      ] Vertex compiled successfully
    [DEBUG  ] [ImagePygame ] Load
    [INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
    [INFO   ] [OSC         ] using for socket
    [DEBUG  ] [Base        ] Create provider from mouse
    [DEBUG  ] [Base        ] Create provider from probesysfs
    [DEBUG  ] [ProbeSysfs  ] using probsysfs!
    [INFO   ] [Base        ] Start application main loop

    But a blank GUI window (notice it's entitled 'Simple' at the top) doesn't do much, does it?

    This is where the Kivy Language file (simple.kv) comes into play.

    Create a file, in the same directory as your Simple.py file (this is important!), and name it simple.kv (the lower case is important too - if not, it won't be found).  The name of this file simple.kv must be named after your class that inherits the App class - you can have a different name for your Python class (e.g., Simpleton) than the class name that extends App, but whatever you have, the .kv file must be named from that class, not the Python file name.

    Because we have a class definition:

    class Simple(App):

    Then the Kivy Language .kv file must be named simple.kv

    If instead, our class that extends App were to be named

    class SimpleA(App):

    Then the Kivy Language .kv file must be named simplea.kv  Notice even the later capitalized 'A' must be changed to 'a'.

    Kivy does make one recommendation, and that is that you name your App extending class to be ended with App, such as SimpleApp, in which case Kivy will strip off the App portion, and only look for simple.kv - the choice is yours.

    Part 2 will move forward from this point, and implement a simple.kv file.

    No comments:

    Post a Comment