Our Project â comic creator

You now have all the necessary concepts to create any interface you want. This section describes the project that we will complete along this section itself and the following three chapters. The basic idea of the project is a comic creator, a simple application to draw a stickman. The following sketch is a wireframe of the GUI we have in mind.

We can distinguish several separate areas in the preceding sketch. Firstly, we need a drawing space (top-right) for our comics. We also need a tool box (top-left) with some drawing tools to draw our figures, and also some general options (second from bottom to top) such as clearing the screen, removing the last element, grouping elements, changing colors, and using the gestures mode. Finally, it will be useful to have a status bar (center-bottom) to provide some information to the user such as quantity of figures or the last action that has been performed. According to what we have learned along this chapter, there are multiple solutions to organize this screen but we will use the following:

We'll use AnchorLayout for the toolbox area in the top-left corner

We'll use Gridlayout of two columns for the drawing tools

We'll use AnchorLayout for the drawing space in the top-right corner

We'll use RelativeLayout to have a relative space to draw in

We'll use AnchorLayout for the general options and status bar area at the bottom

We'll use BoxLayout with vertical orientation to organize the general options on top of the status bar. We'll use also BoxLayout with horizontal orientation for the buttons of the general options, and again for the labels of the status bar.

We'll follow this structure by creating different files for each area: comiccreator.py , comiccreator.kv , toolbox.kv , generaltools.kv , drawingspace.kv , and statusbar.kv . Let's start with comiccreator.py as shown in the following code:

170. # File name: comiccreator.py 171. from kivy.app import App 172. from kivy.lang import Builder 173. from kivy.uix.anchorlayout import AnchorLayout 174. 175. Builder.load_file('toolbox.kv') 176. Builder.load_file('drawingspace.kv') 177. Builder.load_file('generaloptions.kv') 178. Builder.load_file('statusbar.kv') 179. 180. class ComicCreator(AnchorLayout): 181. pass 182. 183. class ComicCreatorApp(App): 184. def build(self): 185. return ComicCreator() 186. 187. if __name__=="__main__": 188. ComicCreatorApp().run()

We are explicitly loading some of the files with the Builder.load_file instruction (from line 175 to 178). There is no need to load the comiccreator.kv because it gets automatically loaded by the ComicCreatorApp name.

Note The Builder class is in charge of loading and parsing all the Kivy language. The load_file method allows us to specify a file containing Kivy language rules that we want to include as part of the project.

For the ComicCreator we choose AnchorLayout . It is not the only option, but it illustrates more clearly within the code that the next level is composed of the AnchorLayout instances. You might wonder whether it might be possible to use a simple Widget . That would have been clear enough but unfortunately it is not possible because Widget doesn't honor the size_hint and pos_hint properties, which are necessary in the AnchorLayout internals.

The following is the code of the comiccreator.kv :

189. # File name: comiccreator.kv 190. <ComicCreator>: 191. AnchorLayout: 192. anchor_x: 'left' 193. anchor_y: 'top' 194. ToolBox: 195. id: _tool_box 196. size_hint: None,None 197. width: 100 198. AnchorLayout: 199. anchor_x: 'right' 200. anchor_y: 'top' 201. DrawingSpace: 202. size_hint: None,None 203. width: root.width - _tool_box.width 204. height: root.height - _general_options.height - _status_bar.height 205. AnchorLayout: 206. anchor_x: 'center' 207. anchor_y: 'bottom' 208. BoxLayout: 209. orientation: 'vertical' 210. GeneralOptions: 211. id: _general_options 212. size_hint: 1,None 213. height: 48 214. StatusBar: 215. id: _status_bar 216. size_hint: 1,None 217. height: 24

The preceding code follows the proposed structure for the comic creator. There are basically three AnchorLayout instances in the first level (lines 191, 198, and 205) and a BoxLayout that organizes the general options and the status bar (line 208).

The lines 197, 213 and 217 set the width of the ToolBox to 100 pixels, the height of the GeneralOptions to 48 pixels, and the height of the StatusBar to 24 pixels respectively. This brings up an interesting problem. We would like that the DrawingSpace uses all the remaining width and height of the screen (no matter what the windows size is). In other words, we want the drawing space as big as possible without covering the other areas (tool box, general options and status bar). In order to solve this, we introduced the use of id (in lines 195, 211, and 215) that allows us to refer to other components inside the Kivy language. On lines 203 and 204 we subtract the tool_box width to the root width (line 203) and the general_options and status_bar height to the root height (line 204). Accessing these attributes is only possible through the id 's we created, which can be used as variables inside the Kivy language.

Let's continue with the toolbox.kv as shown in the following code:

We created a ToolButton class that defines the size of the drawing tools and also introduces a new Kivy Widget: ToggleButton . The difference from the normal Button is that it stays clicked until we click on it again. The following is an example of the toolbox with a ToolButton activated:

Moreover, it can be associated to other ToggleButton instances, so just one of them is clicked at a time. We can achieve this by assigning the same group property (line 222) to the ToggleButton instances we want to react together. In this case, we want all the instances of ToolButton instances to be part of the same group, so we set the group in the ToggleButton class definition (line 222).

On line 224, we implemented the ToolBox as a subclass of GridLayout and we added some character placeholders ( 'O' , '/' , and '?' ) to the ToolButton . These placeholders will be substituted for something appropriate representations in the following chapters.

The following is the code of generaloptions.kv :

In this case, when we used the ToggleButton instances (in lines 241 and 245), we didn't associate them to any group . Here, they are independent from each other and will just keep a mode or state. The preceding code only defines the GeneralOptions class, but there is no functionality associated yet. The following is the resulting screenshot of this area:

The statusbar.kv file is very similar in the way it uses the BoxLayout :

The difference is that it organizes labels and not buttons. The output is as shown in the following screenshot:

The following is the code of drawingspace.kv :

Apart from defining that DrawingSpace is a subclass of RelativeLayout , we introduce the Kivy markup, a nice feature for styling the text of the Label class. It works similar to the XML based languages. For example, in HTML (and XML based language) <b>I am bold</b> will specify bold text. First, you have to activate it (line 257) and then you just embed the text you want to style between [tag] and [/tag] (line 258). You can find the whole tag list and description in the Kivy API, in the documentation for Label at http://kivy.org/docs/api-kivy.uix.label.html.

In the previous example, size and color are self-explanatory; sub refers to the sub-indexed text; b refers to bold and i refers to italics. The following is the screenshot that shows the final GUI of our comic creator:

Along the following chapters we are going to add the respective functionality to this interface that, for now, consists of placeholders. However, it is exciting that with just a few lines of code, we implement a GUI that is ready to go for the rest of the book Comic Creator project. We will be working on its logic from now on.