pygtk-docs r804 - in trunk/2.0: . tut
- From: finlay svn gnome org
- To: svn-commits-list gnome org
- Subject: pygtk-docs r804 - in trunk/2.0: . tut
- Date: Tue, 24 Feb 2009 21:56:46 +0000 (UTC)
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]