pygtk-docs r804 - in trunk/2.0: . tut



Author: finlay
Date: Tue Feb 24 21:56:46 2009
New Revision: 804
URL: http://svn.gnome.org/viewvc/pygtk-docs?rev=804&view=rev

Log:
	* style.css: Add css file to avoid use of deprecated shade.verbatim.

	* html.xsl: Remove usage of shade.verbatim - use style.css instead.

	* Makefile (CSSFILES): Add style.css handling to avoid deprecated
	shade.verbatim usage.

	* README: Add dependency on GraphicsMagick.

	* tut/Credits.xml (url): Add credit to Charles Wilson. Rearrange the
	credits and consolidate PyGTK credits.

	* tut/TipsForWritingPygtkApplications.xml: Add section in Tips from
	Charles Wilson "How to Separate Callback Methods From Signal
	Handlers"



Added:
   trunk/2.0/style.css
Modified:
   trunk/2.0/ChangeLog
   trunk/2.0/Makefile
   trunk/2.0/README
   trunk/2.0/html.xsl
   trunk/2.0/tut/ChangeLog
   trunk/2.0/tut/Credits.xml
   trunk/2.0/tut/TipsForWritingPygtkApplications.xml

Modified: trunk/2.0/Makefile
==============================================================================
--- trunk/2.0/Makefile	(original)
+++ trunk/2.0/Makefile	Tue Feb 24 21:56:46 2009
@@ -1,6 +1,8 @@
 XSLFILES = common.xsl html.xsl tut-html-style.xsl \
 	pdf-style.xsl pdf.xsl devhelp.xsl
 
+CSSFILES = style.css
+
 TUTORIALXMLFILES = \
 tut/pygtk2-tut.xml \
 tut/Adjustments.xml \
@@ -102,7 +104,9 @@
 ${ESOUTPUTDIR}/examples \
 ${ESOUTPUTDIR}/figures
 
-tut-html: pygtk2tutorial ${TUTORIALLINKS} ${TUTORIALXMLFILES} ${XSLFILES}
+tut-html: pygtk2tutorial ${TUTORIALLINKS} ${TUTORIALXMLFILES} ${XSLFILES} \
+		${CSSFILES}
+	cp ${CSSFILES} pygtk2tutorial
 	xsltproc --nonet --xinclude -o pygtk2tutorial/ \
                  --stringparam gtkdoc.bookname pygtk2tutorial \
 		tut-html-style.xsl tut/pygtk2-tut.xml
@@ -130,7 +134,8 @@
 
 tut-srcdist:
 	tar zcf pygtk2-tut.docbook.tgz ${TUTORIALXMLFILES} ${XSLFILES} \
-		$(PICFILES) tut/ChangeLog Makefile examples figures images
+		$(PICFILES) ${CSSFILES} tut/ChangeLog Makefile examples \
+		figures images
 
 tut-dist:
 	tar zhcf pygtk2tutorial.tgz pygtk2tutorial
@@ -151,7 +156,9 @@
 	-(cd pygtk2tutorial/figures; ln -s ../../figures/* .)
 	for x in $(PICSTEMS); do pic2graph <tut/$$x.pic >pygtk2tutorial/figures/$$x.png; done
 
-tut-es-html: ${ESOUTPUTDIR} ${ESTUTORIALLINKS} ${ESTUTORIALXMLFILES} ${XSLFILES}
+tut-es-html: ${ESOUTPUTDIR} ${ESTUTORIALLINKS} ${ESTUTORIALXMLFILES} \
+		${XSLFILES} ${CSSFILES}
+	cp ${CSSFILES} ${ESOUTPUTDIR}
 	xsltproc --nonet --xinclude -o ${ESOUTPUTDIR}/ \
 		--stringparam gtkdoc.bookname  pygtk2tutorial \
 		tut-html-style.xsl tut-es/pygtk2-tut.xml
@@ -177,7 +184,7 @@
 
 tut-es-srcdist:
 	tar zcf pygtk2-tut-es.docbook.tgz ${ESTUTORIALXMLFILES} ${XSLFILES} \
-		tut-es/ChangeLog Makefile examples figures images
+		${CSSFILES} tut-es/ChangeLog Makefile examples figures images
 
 tut-es-dist: tut-html tut-pdf
 	cp pygtk2-tut-es.pdf ${ESOUTPUTDIR}/pygtk2tutorial-es.pdf

Modified: trunk/2.0/README
==============================================================================
--- trunk/2.0/README	(original)
+++ trunk/2.0/README	Tue Feb 24 21:56:46 2009
@@ -13,7 +13,8 @@
 The numbering on the in-line displays of the examples is done with nl(1),
 no options.
 
-The environment required to make HTML includes xsltproc, the DocBook 
-stylesheets, and the GNU program pic2graph (part of the groff distribution)
-which is used for making box-and-arrow diagrams.
+The environment required to make HTML includes xsltproc, the DocBook
+stylesheets, the GNU program pic2graph (part of the groff distribution)
+which is used for making box-and-arrow diagrams and GraphicsMagick (for the
+convert(1) program needed by pic2graph).
  

Modified: trunk/2.0/html.xsl
==============================================================================
--- trunk/2.0/html.xsl	(original)
+++ trunk/2.0/html.xsl	Tue Feb 24 21:56:46 2009
@@ -7,17 +7,11 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version='1.0'>
 
-<xsl:param name="shade.verbatim" select="1"/>
+<xsl:param name="html.stylesheet">style.css</xsl:param>
 <xsl:param name="use.id.as.filename" select="1"/>
 <xsl:param name="chunk.fast" select="1"/>
 <xsl:param name="chunker.output.encoding" select="'utf-8'"/>
 
-<xsl:attribute-set name="shade.verbatim.style">
-  <xsl:attribute name="border">0</xsl:attribute>
-  <xsl:attribute name="bgcolor">#E0E0E0</xsl:attribute>
-  <xsl:attribute name="width">100%</xsl:attribute>
-</xsl:attribute-set>
-
 <xsl:param name="linenumbering.extension" select="1"/>
 <xsl:param name="variablelist.as.table" select="1"/>
 
@@ -50,26 +44,13 @@
         </table>
       </xsl:when>
       <xsl:when test="@role = 'properties' or @role = 'prototypes'">
-  	<xsl:choose>
-    	  <xsl:when test="$shade.verbatim != 0">
-            <table width="100%" xsl:use-attribute-sets="shade.verbatim.style">
-              <tr>
-                <td valign="top">
-                  <xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
-                </td>
-              </tr>
-            </table>
-          </xsl:when>
-	  <xsl:otherwise>
-            <table width="100%" border="0">
-              <tr>
-                <td valign="top">
-                  <xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
-                </td>
-              </tr>
-            </table>
-          </xsl:otherwise>
-        </xsl:choose>
+        <table width="100%" border="0">
+          <tr>
+            <td valign="top">
+              <xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
+            </td>
+          </tr>
+        </table>
       </xsl:when>
       <xsl:otherwise>
         <blockquote class="{local-name(.)}">

Added: trunk/2.0/style.css
==============================================================================
--- (empty file)
+++ trunk/2.0/style.css	Tue Feb 24 21:56:46 2009
@@ -0,0 +1,10 @@
+.programlisting {
+font: monospace;
+background-color: #E0E0E0;
+padding: 5;
+}
+
+pre.synopsis {
+background-color: #E0E0E0;
+padding: 5;
+}

Modified: trunk/2.0/tut/Credits.xml
==============================================================================
--- trunk/2.0/tut/Credits.xml	(original)
+++ trunk/2.0/tut/Credits.xml	Tue Feb 24 21:56:46 2009
@@ -6,29 +6,6 @@
   <chapter id="ch-Credits">
     <title>Credits</title>
 <!-- ===================================================================== -->
-  <sect1 id="sec-PyGTKCredits">
-    <title>PyGTK Credits</title>
-
-    <para>Thanks to:</para>
-
-    <itemizedlist>
-      <listitem>
-        <simpara>Nathan Hurst for the <classname>Plugs</classname> and
-<classname>Sockets</classname> section.</simpara>
-      </listitem>
-      <listitem>
-        <simpara>Alex Roitman for the <classname>FileChooser</classname>
-section.</simpara>
-      </listitem>
-      <listitem>
-        <simpara>Steve George for the example program illustrating editable
-<classname>CellRendererText</classname> and activatable
-<classname>CellRendererToggle</classname>.</simpara>
-      </listitem>
-    </itemizedlist>
-
-  </sect1>
-
   <sect1 id="sec-OriginalGTK+Credits">
     <title>Original GTK+ Credits</title>
 
@@ -136,6 +113,29 @@
      <para>This tutorial was originally adapted from the GTK+
      documentation by John Finlay.</para>
 
+    <para>Thanks to:</para>
+
+    <itemizedlist>
+      <listitem>
+        <simpara>Nathan Hurst for the <classname>Plugs</classname> and
+<classname>Sockets</classname> section.</simpara>
+      </listitem>
+      <listitem>
+        <simpara>Alex Roitman for the <classname>FileChooser</classname>
+section.</simpara>
+      </listitem>
+      <listitem>
+        <simpara>Steve George for the example program illustrating editable
+<classname>CellRendererText</classname> and activatable
+<classname>CellRendererToggle</classname>.</simpara>
+      </listitem>
+      <listitem>
+        <simpara>Charles Wilson for the "How to Separate Callback Methods
+        From Signal Handlers" section in the "Tips For Writing PyGTK
+        Applications" chapter.</simpara>
+      </listitem>
+    </itemizedlist>
+
      <para>Much of <xref
      linkend="sec-TheoryOfPackingBoxes"/> was adapted from the PyGTK
      FAQ item 12.2 <citetitle>How does packing work (or how do I get

Modified: trunk/2.0/tut/TipsForWritingPygtkApplications.xml
==============================================================================
--- trunk/2.0/tut/TipsForWritingPygtkApplications.xml	(original)
+++ trunk/2.0/tut/TipsForWritingPygtkApplications.xml	Tue Feb 24 21:56:46 2009
@@ -60,4 +60,393 @@
 by adhesions with the other one.  It also makes downstream 
 maintainance and bug diagnosis easier.</para>
     </sect1>
-  </chapter>
+<!-- ===================================================================== -->
+<sect1>
+  <title>How to Separate Callback Methods From Signal Handlers</title>
+  <sect2>
+    <title>Overview</title>
+
+    <para>
+      You do not have to store all of your callback methods in one main
+      program file.  You can separate them into classes of their own, in
+      separate files. This way your main program can derive the methods from
+      those classes using inheritance. You end up having all the original
+      functionality with the added benifits of easier maintenance, code
+      reusability, and smaller file sizes, which means less of a burden for
+      text editors.
+    </para>
+  </sect2>
+
+  <sect2>
+    <title>Inheritance</title>
+
+    <para>
+      Inheritance is a way to reuse code. A class can inherit all the
+      functionality of other classes, and the nice thing about inheritance
+      is that we can use it to divide a huge program into logical groups of
+      smaller, more maintainable pieces.
+    </para>
+
+    <para>
+      Now lets spend a second on terminology. A derived class, some call
+      this a subclass or a child class, is a class that derives some of its
+      functionality from other classes.
+
+      A base class, some call it a superclass or a parent class, is what the
+      derived class inherits from.
+    </para>
+
+    <para>
+      Below is a short example to help you become familiar with
+      inheritance. You can try this out in the python interpreter to gain
+      some first hand experience.
+    </para>
+
+    <para>
+      Create two base classes:
+    </para>
+
+    <programlisting>
+class base1:
+   base1_attribute = 1
+   def base1_method(self):
+     return "hello from base class 1"
+
+class base2:
+   base2_attribute = 2
+   def base2_method(self):
+     return "hello from base class 2"
+    </programlisting>
+
+    <para>
+      Then create a derived class that inherits from these two base classes:
+    </para>
+
+    <programlisting>
+class derived(base1, base2):  #a class derived from two base classes
+   var3 = 3                     
+    </programlisting>
+
+    <para>
+      Now the derived class has all the functionality of the base classes. 
+    </para>
+
+    <programlisting>
+x = derived()        # creates an instance of the derived class
+x.base1_attribute    # 1
+x.base2_attribute    # 2
+x.var3               # 3
+x.base1_method()     # hello from base class 1
+x.base2_method()     # hello from base class 2
+    </programlisting>
+
+    <para>
+      The object called x has the ability to access the variables and
+      methods of the base classes because it has inherited their
+      functionality.  Now lets apply this concept of inheritance to a PyGTK
+      application.
+    </para>
+
+  </sect2>
+
+
+  <sect2>
+    <title>Inheritance Applied To PyGTK</title>
+
+    <para>
+      Create a file called gui.py, then copy this code into it.
+    </para>
+
+    <programlisting>
+#A file called: gui.py
+
+import pygtk                                                  
+import gtk                                                   
+
+# Create a class definition called gui                                    
+class gui:
+  #                                                     
+  #          CALLBACK METHODS
+  #------------------------------------                                                                                                
+  def open(self, widget):                              
+    print "opens stuff"                                       
+  def save(self, widget):                              
+    print "save stuff"                                        
+  def undo(self, widget):                              
+    print "undo stuff"                                       
+  def destroy(self, widget):
+    gtk.main_quit()
+         
+                                                        
+  def __init__(self): 
+    #
+    #        GUI CONSTRUCTION CODE
+    #-----------------------------------------------
+    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+    self.window.show()                                                              
+    self.vbox1 = gtk.VBox(False, 25)
+    self.window.add(self.vbox1)
+    open_button = gtk.Button(label="Open Stuff")
+    open_button.set_use_stock(True)
+    self.vbox1.pack_start(open_button, False, False, 0)
+    open_button.show() 
+    save_button = gtk.Button(label="Save Stuff")
+    self.vbox1.pack_start(save_button, False, False, 0)
+    save_button.show()
+    undo_button = gtk.Button(label="Undo")
+    self.vbox1.pack_start(undo_button, False, False, 0)
+    undo_button.show()
+    self.vbox1.show()
+    #
+    #        SIGNAL HANDLERS
+    #------------------------------------------------                                                        
+    open_button.connect("clicked", self.open)          
+    save_button.connect("clicked", self.save)           
+    undo_button.connect("clicked", self.undo) 
+    self.window.connect("destroy", self.destroy)          
+                                                              
+  def main(self):                                             
+   gtk.main()                                                 
+                                                              
+if __name__ == "__main__":                                    
+ gui_instance = gui()       # create a gui object             
+ gui_instance.main()        # call the main method         
+    </programlisting>
+
+    <para>
+      If your run this program you will find it is just a simple window with
+      some buttons. As the program is organized right now, all of the code
+      is in one single file.  But in a moment, you will find out how to
+      break that program up into multiple files.  The idea is to take those
+      four callback methods out of the gui class and put them into classes
+      of their own, in separate files. Now if you had hundreds of callback
+      methods you would try and group them in some logical way, for example,
+      you might put all of your methods that deal with input/output into the
+      same class, and you would make other classes for other groups of
+      methods as well.
+    </para>
+
+    <para>
+      The first thing we have to do is make some classes for the methods in
+      the gui.py file. Create three new text files, and name them io.py,
+      undo.py, and destroy.py, and put these files in the same directory as
+      the gui.py file.  Copy the code below into the io.py file.
+    </para>
+
+    <programlisting>
+class io:                                                       
+  def open(self, widget):                                  
+    print "opens stuff"                                          
+                                      
+  def save(self, widget):                                  
+    print "save stuff"                                           
+    </programlisting>
+
+    <para>
+      These are the two callback methods, open and save, from the gui.py
+      program.  Copy the next block of code into the undo.py file.
+    </para>
+
+    <programlisting>
+class undo:                                                      
+  def undo(self, widget):                                  
+    print "undo stuff" 
+    </programlisting>
+
+    <para> 
+      This is the undo_method from gui.py.  And finally, copy the code below
+      into destroy.py.
+    </para>
+
+    <programlisting>
+import gtk
+
+class destroy:
+  def destroy(self, widget):
+    gtk.main_quit()                                                            
+    </programlisting>
+
+    <para>
+      Now all the methods are separated into classes of their own.
+    </para>
+
+    <graphic fileref="images/important.gif"></graphic>
+    <important>
+      <para>
+        In your future programs you will want to import things like gtk,
+        pango, os ect...  into your derived class(the one with all of your
+        gui initialization code), but also, remember to import any modules
+        or classes you need into your base classes too. Sometimes you might
+        create an instance of a gtk widget in a base class method, in that
+        case import gtk.
+      </para>
+
+      <para>
+        This is just an example of a base class where you would be required
+        to import gtk.
+      </para>
+
+      <programlisting>
+  import gtk                                                        
+                                                                           
+  class Font_io                                                     
+    def Font_Chooser(self,widget):                                  
+      self.fontchooser = gtk.FontSelectionDialog("Choose Font")                                  
+      self.fontchooser.show()    
+      </programlisting>
+
+      <para>
+        Notice it defines a gtk widget, a font selection dialog. You would
+        normally import gtk in your main class(the derived class) and
+        everything would be ok. But the second you take this Font_Chooser
+        method out of your main class and put it into a class of its own,
+        and then try to inherit from it, you would find you get an error.
+        In this case, you would not even see any error until you were
+        running the program.  But when you try to use the Font_Chooser, you
+        would find that gtk is not defined, even though you have imported it
+        in your derived class. So just remember that when you create base
+        classes, you need to add their proper imports too.
+      </para>
+    </important>
+
+    <para>
+      With your three classes in three separate py files, you now need to
+      change the code in the gui.py file in three ways.
+    </para>
+
+    <orderedlist numberation="arabic"> 
+      <listitem><para>Import the classes you have created.</para></listitem>
+      <listitem><para>Change your class definition.</para></listitem>
+      <listitem><para>Delete your callback methods.</para></listitem>
+    </orderedlist>
+
+    <para>
+      The updated code below shows how to do this.
+    </para>
+
+
+    <programlisting>
+#A file called:  gui.py
+#(updated version)
+#(with multiple inheritance)
+
+import pygtk                                                  
+import gtk  
+                       
+from io import file_io                       #                                
+from undo import undo                        # 1. Import Your Classes
+from destroy import destroy                  #
+
+# Create a class definition called gui                                    
+class gui(io, undo, destroy):                # 2. Changed Class Definition
+                                             # 3. Deleted Callbacks
+  def __init__(self): 
+    #
+    #        GUI CONSTRUCTION CODE
+    #-----------------------------------------------
+    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+    self.window.show()
+    self.vbox1 = gtk.VBox(False, 25)
+    self.window.add(self.vbox1)
+    open_button = gtk.Button(label="Open Stuff")
+    open_button.set_use_stock(True)
+    self.vbox1.pack_start(open_button, False, False, 0)
+    open_button.show() 
+    save_button = gtk.Button(label="Save Stuff")
+    self.vbox1.pack_start(save_button, False, False, 0)
+    save_button.show()
+    undo_button = gtk.Button(label="Undo")
+    self.vbox1.pack_start(undo_button, False, False, 0)
+    undo_button.show()
+    self.vbox1.show()
+    #
+    #        SIGNAL HANDLERS
+    #------------------------------------------------
+    open_button.connect("clicked", self.open_method)          
+    save_button.connect("clicked", self.save_method)           
+    undo_button.connect("clicked", self.undo_method) 
+    self.window.connect("destroy", self.destroy)          
+                                                              
+  def main(self):                                             
+   gtk.main()                                                 
+                                                              
+if __name__ == "__main__":                                    
+ gui_instance = gui()       # create a gui object             
+ gui_instance.main()        # call the main method
+    </programlisting>
+
+    <para>
+      These three lines are new:
+    </para>
+
+    <programlisting>
+       from io import io                                   
+       from undo import undo                                          
+       from destroy import destroy     
+    </programlisting>
+
+    <para>
+      The import statements are of the form:
+    </para>
+
+    <programlisting>
+       from [filename of your class file] import [class name]
+    </programlisting>
+
+    <para>
+      Here is the class definition change:
+    </para>
+
+    <programlisting>
+       class gui(io, undo, destroy):
+    </programlisting>
+
+    <para>
+      The names of the base classes go between the parenthesis in the class
+      definition.  Now the gui class has become a derived class, and is able
+      to use all the attributes and methods defined in its base
+      classes. Also, the gui class is inheriting from multiple classes(two
+      or more), this is known as multiple inheritance.
+    </para>
+
+    <para>
+      Now change the gui.py file to the updated version and run the program
+      again.  You will notice it works exactly the same, except now all the
+      callback methods are in separate classes, being inherited by the gui
+      class.
+    </para>
+
+    <para>
+      There is just one other matter of interest to take note of.  As long
+      as your gui.py program and your base class files are all in the same
+      directory, everything will work just fine. But if you want to create
+      another directory inside there called classes, in which to organize
+      your files of base classes, then you will need to add two more lines
+      of code with the rest of your import statements in gui.py, like this:
+    </para>
+
+    <programlisting>
+        import sys
+        sys.path.append("classes")
+    </programlisting>
+
+    <para>
+      where classes is the name of the directory you store your classes
+      in. This lets Python know where to look for your classes.  Try it
+      out. Just make a directory called classes in the directory where you
+      have the gui.py program. Then put your three base class files into
+      this classes directory.  Now add the two lines of code show above to
+      the top of the gui.py file.  And thats it!
+    </para>
+
+    <para>
+      One final note for those that use py2exe for compiling python
+      programs. Put your base classes in your Python directory, then py2exe
+      will included them in the compiled version of your program just like
+      any other Python module.
+    </para>
+
+  </sect2> 
+
+</sect1>
+</chapter>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]