This part 1 of th Quickly tutorial. This part is will introduce some key quickly commands, editing a user interface in Glade, and editing code in Gedit. This part of the tutorial will familiarize you with these three tools, and how they work together with python and pygtk so that you can quickly build applications.
Creating an empty but working program couldn't be simpler. First, open a terminal window to type commands into. When it's open, type the command:
This will create a super_text sub directory containing a complete directory tree and files for an empty python appliction. The command finishes by running the newly created empty application.
They are populated and set up, and you can resize the window. Notice that quickly interfered that the application title is "Super Text". Only a few of menu items do anything in the empty application, Help->About, Edit->Preferences, and File->Quit.
Close the application by closing the window or using the Quit command. Since the empty application isn't installed into Ubuntu yet, you can't start the application from the application menu yet. To start the applicaton, use the terminal to first cd into the new subdirectory, and then issue the command to start the program.
Quickly programs use Glade to edit the user interface. Start Glade with quickly in order to set up Glade for editing the empty applicaton. Don't start glade directly, or it won't load the necessary catalogue files for editing the classes that were automaticaly generated by quickly.
Glade will open with the project loaded up and ready to edit.
Use the Project Menu to choose "SuperTextWindow.ui" for editing.
We want to create a text area for typing into. There are some default Widgets added to the Window. We won't need these so we'll start with deleting them. Click on the label, and press delete, and it will disappear from the window.
Do the same with the image widget. This leave us two free slots.
We'll use the bottom slot to add a TextView widget for the user to type into. In the toolbox, click on the TextView widget. Then click in the empty slot.
Make sure you save the file in Glade, or your changes won't take! Then run the application from terminal again. The window now has a place where the user can type.
Now we'll add the entry field for the title, and also a label for it. We'll use the top empty slot for that. First, click on Horizontal Box (HBox) from the "Containers" section of the pallette, and then click on the top slot. A dialog box will open, tell it that you want two items.
The HBox is a container that arranges it's children horizontally. Add a label to the empty left hand box, and a Text Entry to the right hand one.
Before going on, let's clean up the UI just a tad here. Select the new HBox from the treeview in the inspector window. Then go to the Packing tab, and set Expand and Fill to "No".
Go to the General tab, and set spacing to 5.
Set expand and fill to "no" for the label, but keep it "yes" for the entry. Set the padding for both to 5 (also on the Packing tab).
After the user types something, they may want to save it. A File->Save menu item was automatically created when the empty applicaton was created, but it's not hooked up to any code. To make Save work, we need tell the menu item what function to call, and then create a function to actually do the saving.
To tell the menu item what function to call. If glade is not still open, open up the appliction in glade:
Click on the file menu, and the menu opens as if the application were running.
Choose the Save menu item, and it will be selected in Glade.
Then choose the "Signals" tab of the properties window.
In pygtk, menu items are "activated" when a user chooses the item from the menu. Since we want a function to run when the user chooses Save, we want to specify a function to respond to the activate signal from the menu item. We'll call the function "save_file". Simply type the function name into the box for the activate signal. Make sure to save the glade file.
Of course, this won't make the file actually save, because we haven't created the "save_file" function yet. So it's time to write a little code. The code for SuperTextWindow is stored in the file SuperTextWindow.py.
Use the quickly edit command to start editing your code files:
This will open the default Ubuntu text editor "Gedit" with any python files in the python directory.
SuperTextWindow.ui is now expecting to find a function SuperTextWindow.save_file(), so we simply add one to the SuperTextWindow class:
This will print the word "save" to the terminal when run. The method signature is the standard signature expected in a signal handler. If you are new to python, be sure to copy the indentations exactly, as the indentation level is very important in python.
Save the file, and run it again:
Choose "File->Save" from the menu, and you'll see the word "save" printing out interminal. That's all there is to hookig up the functions!
Now we'll write a little code in the signal handler to actually save the text. Because we want it to be easy for users to do things like syncronize their Super Text documents between computers, back it up, etc... we'll use couchdb as our backend. Note that if you are not interested in learning about how to save to and read from couchdb, you can just snipe the code. First, you may need to install couchdb and python-couchdb. The fastest way to do this is from ther terminal:
After couchdb and python-couchdb is installed, you can write the code. The code will do the following:
Add these import statements along with the other imports to the top of SuperTextWindow.py:
We'll just hard code a reference to the database on the user's computer. If we want to point to a couchdb instance somewhere else later, it will be easy to change. We also want to name the datbase something reasonably unique, we'll use "super_text". Since we want these lines to run every time the Super Text window is created, put these at the end of the finish_initializing function:
Now in our save_file function, we want to get a reference to the database. However, if this is the first time that the application is run, the database may not have been created yet. Fortunately, it's an easy matter to check for the database, and if it's not there to create it.
In pygtk, TextView widgets have a text buffer that stores the text. So you ask the TextView for it's TextBuffer, and then you ask the TextBuffer for the text. You use iters to determine from which part of the text buffer you want text. Since we want all the text, it's easy to just get the start and end iters.
A document in couch is essentially a python dictionary. So we can save the document to couch like this:The "record_type" field is not really required, but among other things, it makes it easy to fetch the documents later. By convention, we use a url to specify the record type. This provides a place for other developers to go to read about the record type. The description only needs to be human readable. Couchdb is not a typed database, so don't expect that the url will have any kind of schema definition or anything. You can use whatever url you want, and put whatever you want at that URL.
Before we just write the new document though, we have to take note of the fact that couch will allow you to create as many documents as you want with the same title. We probably don't want this, so we we'll have to write a little code to check if there is already a document in couch with the same title, and if there is, update that document rather than create a new one.
To do this:
This all may sound very weird, but in code, it's not quite so complicated:
Couchdb makes it really easy to see if your save function is working. You can just point your web browser at it and explore the database:
To open a saved document, the user will type the title of the document that they want to open in the text entry, and choose "Open" from the main menu. If there is no matching document there, it will just clear out the text view, ready for input. This is probably not too intuitive, so we'll add a dialog box for prompting the user for the title, but that's for later in the tutorial. For now, we'll just use the same text entry field.
Follow these steps:
So the open_file function looks like so:
To make them work, add these functions to the SuperTextWindow class, and save. Then go back and connect the functions to the activate signals for the Open and New menu items.
When Quickly created your application, it automatically added it to Bazaar, a source code versioning system. You can use Bazaar to roll back mistake, see code history, compare versions, etc... Quickly has a convenience function for backing up your work:
This will call "$bzr add" and then "$bzr commit -m [your meesage]" for you.