File: krishnakumar.html

package info (click to toggle)
lg-issue78 2-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 3,112 kB
  • ctags: 238
  • sloc: sh: 129; makefile: 68
file content (371 lines) | stat: -rw-r--r-- 17,938 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
<!--startcut  ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Rapid application development using PyGTK LG #78</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->

<CENTER>
<A HREF="http://www.linuxgazette.com/">
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png" 
	WIDTH="600" HEIGHT="124" border="0"></A> 
<BR>

<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="holm.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue78/krishnakumar.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="qubism.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>

<!--endcut ============================================================-->

<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>

<P> <HR> <P> 
<!--===================================================================-->

<center>
<H1><font color="maroon">Rapid application development using PyGTK</font></H1>
<H4>By <a href="mailto:krishnakumar_r@bharatmail.com">Krishnakumar R.</a></H4>
</center>
<P> <HR> <P>  

<!-- END header -->




<EM>In a competitive world, there is a definite edge to developing applications as rapidly as possible. This can be done using PyGTK which combines the robustness of Python and the raw power of GTK. This article is a hands on tutorial on building a scientific calculator using pygtk. </EM>
<HR>
<H2><A NAME="s1">1. What is PyGTK ?</A></H2>

<P>
Well, let me quote from the PyGTK source distribution:
<PRE>
   "This archive contains modules that allow you to use gtk in Python
   programs.  At present, it is a fairly complete set of bindings.
   Despite the low version number, this piece of software is quite
   useful, and is usable to write moderately complex programs."
                                                - README, pygtk-0.6.4
</PRE>
<H2><A NAME="s2">2. What are we going to do ?</A></H2>

<P>We are going to build a small scientific calculator using pygtk. I will explain each stage, in detail. Going through each step of this process will help one to get acquainted with pygtk. I have also put a link to the complete source code at the end of the article. 
<H2><A NAME="s3">3. Packages and Basic knowledge you should have</A></H2>

<P>
<DL>
<DT><B>python</B><DD><P>This package is available with almost every Linux distributions. My explanation would be based on Python 1.5.2 installed on a Linux RedHat 6.2 machine. It would be good if you know how to program in python. Even if you do not know python programming, do not worry ! Just follow the instructions given in the article.
<DT><B>pygtk</B><DD><P>Newer versions of this package is available from : 
<OL>
<LI> 
<A HREF="ftp://ftp.daa.com.au/pub/james/python">ftp://ftp.daa.com.au/pub/james/python</A></LI>
<LI>
<A HREF="ftp://ftp.gtk.org/pub/gtk/python/">ftp://ftp.gtk.org/pub/gtk/python/</A></LI>
<LI>
<A HREF="ftp://ftp.python.org/pub/contrib/Graphics">ftp://ftp.python.org/pub/contrib/Graphics</A></LI>
</OL>

My explanation would be based on pygtk-0.6.4.
</DL>
<H2><A NAME="s4">4. Let us start</A></H2>

<P>The tutorial has been divided into three stages. The code and the corresponding output are given with each stage. 
<H2><A NAME="s5">5. Stage 1 - Building a Window </A></H2>

<P>First we need to create a window. Window is actually a container. The buttons tables etc. would come within this window.
Open a new file <CODE>stage1.py</CODE>, using an editor. Write in the following lines to it :
<P>
<HR>
<PRE>
from gtk import *

win = GtkWindow()

def main():
        win.set_usize(300, 350)
        win.connect("destroy", mainquit)
        win.set_title("Scientific Calculator")
        win.show()
        mainloop()

main()
        
</PRE>
<HR>
<P>First line is for importing the methods from the module named gtk. That means we can now use the functions present in the gtk library. 
<P>Then we make an object of type GtkWindow and name it as win. After that we set the size of the window. The first argument is the breadth and the second argument is the height. We also set the title of our window. Then we call the method by name show. This method will be present in case of all objects. After setting the parameters of a particular object, we should always call show. Only when we call the show of a particular object does it becomes visible to the user. Remember that although you may create an object logically; until you call show of that object, the object will not be physically visible.
<P>
<P>We connect the signal delete of the window to a function mainquit. The mainquit is an internal function of the gtk by calling which the presently running application can be closed. Do not worry about signals. For now just understand that whenever we delete the window (may be by clicking the cross mark at the window top), the mainquit will be called. That is, when we delete the window, the application is also quit.
<P>mainloop() is also an internal function of the gtk library. When we call the mainloop, the launched application waits in a loop for some event to occur. Here the window appears on the screen and just waits. It is waiting in the 'mainloop', for our actions. Only when we delete the window does the application come out of the loop.
<P>Save the file. Quit the editor and come to the shell prompt. At the prompt type :
<P><CODE>python stage1.py </CODE>
<P>Remember, you should be in Xwindow to view the output.
<P>A screen shot of output is shown below.

<P ALIGN="CENTER">
<IMG SRC="misc/krishnakumar/stage1.png" HEIGHT="420" WIDTH="350" ALT="stage1.png">
</P>
<P>   
<BR>



<H2><A NAME="s6">6. Stage 2 - Building the table and buttons</A></H2>

<P>Let us start writing the second file, <CODE>stage2.py</CODE>. Write the following code to file <CODE>stage2.py</CODE>.
<HR>
<PRE>


from gtk import *
 
rows=9
cols=4
 
 
win = GtkWindow()
box = GtkVBox()
table = GtkTable(rows, cols, FALSE)
text = GtkText()
close  = GtkButton("close")
 
button_strings=['hypot(','e',',','clear','log(','log10(','pow(','pi','sinh(','cosh(','tanh(','sqrt(','asin(',
'acos(','atan(','(','sin(','cos(','tan(',')','7','8','9','/','4','5','6','*','1','2','3','-', '0','.','=','+'
]
button = map(lambda i:GtkButton(button_strings[i]), range(rows*cols))
 
 
 
 
def main():
        win.set_usize(300, 350)
        win.connect("destroy", mainquit)
        win.set_title("Scientific Calculator")
 
        win.add(box)
        box.show()
 
        text.set_editable(FALSE)
        text.set_usize(300,1)
        text.show()
        text.insert_defaults(" ")
        box.pack_start(text)
 
        table.set_row_spacings(5)
        table.set_col_spacings(5)
        table.set_border_width(0)                                                                            

        box.pack_start(table)
        table.show()
 
        for i in range(rows*cols) :
              y,x = divmod(i, cols)
              table.attach(button[i], x,x+1, y,y+1)
              button[i].show()
 
        close.show()
        box.pack_start(close)
 
        win.show()
        mainloop()
 
main()
                                                   
</PRE>
<HR>
<P>The variables <CODE>rows</CODE> and <CODE>cols</CODE> are used to store the number of rows and columns, of buttons, respectively. Four new objects -- the table, the box, the text box  and a button are created. The argument to <CODE>GtkButton</CODE> is the label of the button. So <CODE>close</CODE> is a button with label as "closed".
<P>The array , <CODE>button_strings</CODE> is used to store the label of buttons. The symbols that appear in the keypad of scientific calculator are used here. The variable <CODE>button</CODE> is an array of buttons. The <CODE>map</CODE> function creates rows*cols number of buttons. The label of the button is taken from the array <CODE>button_strings</CODE>. So the <CODE>i</CODE>the button will have the <CODE>i</CODE>th string from <CODE>button_strings</CODE> as label. The range of <CODE>i</CODE> is from 0 to rows*cols-1. 
<P>We insert a box into the window. To this box we insert the table. And in to this table we insert the buttons. 
Corresponding <CODE>show</CODE> of window, table and buttons are called after they are logically created. With <CODE>win.add</CODE> we add the box to the window. 
<P>Use of <CODE>text.set_editable(FALSE)</CODE> will set the text box as non-editable. That means we cannot externally add anything to the text box, by typing. The <CODE>text.set_usize</CODE>, sets the size of the text box and the <CODE>text.insert_defaults</CODE> inserts the null string as the default string to the text box. This text box is packed into the starting of the <CODE>box</CODE>.
<P>After the text box we insert the table in to the box. Setting the attributes of the table is trivial. The for loop inserts 4 buttons into 9 rows. The statement <CODE>y,x = divmod(i, cols)</CODE> would divides the value of i by cols and, keeps the quotient in y and the remainder in x.  
<P>Finally we insert the close button to the box. Remember, <CODE>pack_start</CODE> would insert the object to the next free space available within the box. 
<P>Save the file and type
<P> 
<CODE> python stage2.py </CODE> 
<P>A screen shot of the output is given below.

 
<P ALIGN="CENTER">
<IMG SRC="misc/krishnakumar/stage2.png" HEIGHT="420" WIDTH="350" ALT="stage2.png">
</P>
<P>
<BR>  





<H2><A NAME="s7">7. Stage 3 - Building the backend for the calculator</A></H2>

<P>Some functions are to be written to make the application do the work of calculator. This functions have been termed as the backend. These are the lines that are to be typed in to <CODE>scical.py</CODE>. This is the final stage. The <CODE>scical.py</CODE> contains the finished output. The program is given below :
<P>
<HR>
<PRE>
from gtk import *
from math import *
 
toeval=' '
rows=9
cols=4
 
win = GtkWindow()
box = GtkVBox()
table = GtkTable(rows, cols, FALSE)
text = GtkText()
close  = GtkButton("close")
 
button_strings=['hypot(','e',',','clear','log(','log10(','pow(','pi','sinh(','cosh(','tanh(','sqrt(','asin(','acos(','atan(','(','sin(','cos(','tan(',')','7','8','9','/','4','5','6','*','1','2','3','-', '0','.','=','+']
button = map(lambda i:GtkButton(button_strings[i]), range(rows*cols))

def myeval(*args):
        global toeval
        try   :
                b=str(eval(toeval))
        except:
                b= "error"
                toeval=''
        else  : toeval=b                                    
        text.backward_delete(text.get_point())
        text.insert_defaults(b)



def mydel(*args):
        global toeval
        text.backward_delete(text.get_point())
        toeval=''
 
def calcclose(*args):
        global toeval
        myeval()
        win.destroy()
 
def print_string(args,i):
        global toeval
        text.backward_delete(text.get_point())
        text.backward_delete(len(toeval))
        toeval=toeval+button_strings[i]
        text.insert_defaults(toeval)
 
 
def main():
        win.set_usize(300, 350)
        win.connect("destroy", mainquit)
        win.set_title("Scientific Calculator: scical (C) 2002 Krishnakumar.R, Share Under GPL.")
 
        win.add(box)
        box.show()
 
        text.set_editable(FALSE)                       
        text.set_usize(300,1)
        text.show()
        text.insert_defaults(" ")
        box.pack_start(text)
 
        table.set_row_spacings(5)
        table.set_col_spacings(5)
        table.set_border_width(0)
        box.pack_start(table)
        table.show()
 
        for i in range(rows*cols) :
              if i==(rows*cols-2) : button[i].connect("clicked",myeval)
              elif  (i==(cols-1)) : button[i].connect("clicked",mydel)
              else                : button[i].connect("clicked",print_string,i)
              y,x = divmod(i, 4)
              table.attach(button[i], x,x+1, y,y+1)
              button[i].show()
 
        close.show()
        close.connect("clicked",calcclose)
        box.pack_start(close)
 
        win.show()
        mainloop()
 
main()                                              
</PRE>
<HR>
<P>A new variable <CODE>toeval</CODE> has been included. This variable stores the string that is to be evaluated. The string to be evaluated is present in the text box, at the top. This string is evaluated when the <CODE>=<CODE> button is pressed. This is done by calling the function <CODE>myeval</CODE>. The string contents are evaluated, using python function <CODE>eval</CODE> and the result is printed in the text box. If the string cannot be evaluated (due to some syntax errors), then a string 'error' is printed. We use the try and except for this process.
<P>Pressing any button (using a mouse)  other than the <CODE>clear</CODE>, the <CODE>close</CODE>  and the <CODE>=</CODE>, will trigger the function <CODE>print_string</CODE>. This function first clears the text box. Now it appends the string corresponding to the button pressed, to the variable <CODE>toeval</CODE> and then displays <CODE>toeval</CODE> in the text box. 
<P>If we press the <CODE>close</CODE> button then, the function <CODE>calcclose</CODE> is called, which destroys the window.  If we press the <CODE>clear</CODE> button then the function <CODE>mydel</CODE> is called and the text box is cleared. In the function main, we have added the 3 new statements to the for loop. They are for assigning the corresponding functions to the buttons. Thus the <CODE>=</CODE> button is attached to <CODE>myeval</CODE> function, the <CODE>clear</CODE> is attached to <CODE>mydel</CODE> and so on.
<P>Thus we have the complete scientific calculator ready. Just type 
<CODE> python scical.py</CODE>
at the shell prompt and you have the scientific calculator running.
<P>A snapshot of final application is given below.
<P>

 
<P ALIGN="CENTER">
<IMG SRC="misc/krishnakumar/scical.png" HEIGHT="420" WIDTH="350" ALT="scical.png">
</P>
<P>
<BR>  









<H2><A NAME="s8">8. Conclusion</A></H2>

<P>The source code of the stages can be downloaded by clicking at the links below.
<P>
<OL>
<LI> 
<A HREF="misc/krishnakumar/stage1.py.txt">stage1.py</A></LI>
<LI>
<A HREF="misc/krishnakumar/stage2.py.txt">stage2.py</A></LI>
<LI>
<A HREF="misc/krishnakumar/scical.py.txt">scical.py</A></LI>
</OL>
<P>
<P>They have all .txt extension. Remove this extension and run the programs. For example change stage1.py.txt to stage1.py before executing.

<P>Lot of example programs will be given in the examples directory, which come along with the pygtk package. In Linux, RehHat 6.2 you can find it under /usr/doc/pygtk-0.6.4/examples/ directory. Run those programs and  read their source code. This will give you ample help on developing complex applications.
<P>Happy Programming. Good Bye !




<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P> 
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Krishnakumar R.</H4>
<EM>Krishnakumar is a final year B.Tech student at Govt. Engg. College Thrissur,
Kerala, India.  His journey into the land of Operating systems started with
module programming in linux . He has built a routing operating system by name
GROS.(Details available at his home page:
<A HREF="http://www.askus.way.to">www.askus.way.to</A> ) His other
interests include Networking, Device drivers, Compiler Porting  and Embedded systems.</EM>

<!-- *** END bio *** -->

<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P --> 
<H5 ALIGN=center>

Copyright &copy; 2002, Krishnakumar R..<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR> 
Published in Issue 78 of <i>Linux Gazette</i>, May 2002</H5>
<!-- *** END copyright *** -->

<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="holm.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue78/krishnakumar.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="qubism.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->