PyGTK/Hello World Tutorial: Difference between revisions

From OLPC
Jump to navigation Jump to search
m (how to install)
 
(23 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{translations}}
<font style="color:green">Welcome!</font> This is a guide for how to create a simple PyGTK Activitiy.


<table border="0">
<tr>
<td>__TOC__</td>
<td valign="top" align="center" style="padding-left:20px;">
<font style="color:green">'''Welcome!'''</font> This is a simple tutorial for<br> creating Activities using PyGTK.


[[Image:Activity-gtktest.png]]
</td>
</tr>
</table>
== About PyGTK ==
== About PyGTK ==
[http://www.pygtk.org/ PyGTK] is a framework to create a user interface with python. It's quick, easy and very good [http://www.pygtk.org/docs/pygtk/index.html documented].
[http://www.pygtk.org/ PyGTK] is a framework to create a user interface with python. It's quick, easy and very well [http://www.pygtk.org/docs/pygtk/index.html documented].




== Getting started ==
== Getting started & download ==
Please start with this first steps:
Please start with these first steps:
# Make yourself familiar with [http://www.pygtk.org/ PyGTK] and write few demo applications
# Make yourself familiar with [http://www.pygtk.org/ PyGTK] and write few demo applications
#* [http://www.moeraki.com/pygtktutorial/pygtk2tutorial/index.html Tutorial]
#* [http://www.moeraki.com/pygtktutorial/pygtk2tutorial/index.html Tutorial]
#* [http://www.pygtk.org/docs/pygtk/index.html PyGTK Reference]
#* [http://www.pygtk.org/docs/pygtk/index.html PyGTK Reference]
# Use [http://glade.gnome.org/ Glade] (or [http://gazpacho.sicem.biz/ Gazpacho]) to design an user interface, and use that in an application. This step is optional, but recommendet.
# Use [http://glade.gnome.org/ Glade] (or [http://gazpacho.sicem.biz/ Gazpacho]) to design an user interface, and use that in an application. This step is optional, but recommended.

Save the tutorial in your hard disk ([http://wiki.laptop.org/index.php?title=PyGTK/Hello_World_Tutorial&printable=yes here])


At this point we assume that you made at least one "hello-world" application with pygtk ''':)'''
At this point we assume that you made at least one "hello-world" application with pygtk ''':)'''


The source codes from this examples are downloadable here:
The source code from these examples are downloadable here:
* [http://wiki.laptop.org/images/b/ba/Gtktest.xo gtktest.xo]
* [http://wiki.laptop.org/images/b/ba/Gtktest.xo gtktest.xo]
* [http://wiki.laptop.org/images/0/02/Gtktest-glade.xo gtktest-glade.xo]
* [http://wiki.laptop.org/images/0/02/Gtktest-glade.xo gtktest-glade.xo]



= Basic Activity Structure =
= Basic Activity Structure =
Line 28: Line 40:


== gtktest.activity/MANIFEST ==
== gtktest.activity/MANIFEST ==
This text-file contains the structure of the Activity. Automatically created by setup.py. In our example:
This text-file contains the structure of the Activity automatically created by setup.py. In our example:
MANIFEST
gtktest.activity/
setup.py
gtktest.activity/MANIFEST
gtktest.activity/setup.py
activity/activity-gtktest.svg
gtktest.activity/activity/
activity/activity.info
gtktest.activity/activity/activity-gtktest.svg
activity.py
gtktest.activity/activity/activity.info
gtktest.py
gtktest.activity/activity.py
gtktest.activity/gtktest.py



== gtktest.activity/setup.py ==
== gtktest.activity/setup.py ==
The basic version of setup.py looks like this:
This is a script which creates the MANIFEST and zipps everything into gtktest.xo.

#!/usr/bin/env python
from sugar.activity import bundlebuilder
bundlebuilder.start()

However, here is a more advanced one which also works in a limited fashion on machines where the Sugar environment is not present.

#!/usr/bin/env python
#!/usr/bin/env python
try:
try:
from sugar.activity import bundlebuilder
from sugar.activity import bundlebuilder
bundlebuilder.start("gtktest")
bundlebuilder.start()
except ImportError:
except ImportError:
import os
import os
Line 55: Line 71:


== gtktest.activity/activity/ ==
== gtktest.activity/activity/ ==
This directory contains informations for sugar.
This directory contains information for sugar.
fds fdg



== gtktest.activity/activity/activity-gtktest.svg ==
== gtktest.activity/activity/activity-gtktest.svg ==
Line 63: Line 79:


== gtktest.activity/activity/activity.info ==
== gtktest.activity/activity/activity.info ==
This file contains informations for sugar about our Activity.
This file contains information for sugar about our Activity.
[Activity]
[Activity]
name = gtktest
name = gtktest
Line 71: Line 87:
activity_version = 1
activity_version = 1
show_launcher = yes
show_launcher = yes



== gtktest.activity/activity.py ==
== gtktest.activity/activity.py ==
This file is the core of the Activity, which loads the toolbar and window, attaches a GTK Widget to itself, and imports the Activity's source code source code from gtktest.py. This structure has a few advantages:
This file is the core of the Activity, which loads the toolbar and window, attaches a [[GTK]] Widget to itself, and imports the Activity's source code source code from '''gtktest.py'''. This structure has a few advantages:
# No need to change activity.py for any code updates
# No need to change activity.py for any code updates
# Run gtktest.py as standalone or imported from activity.py
# Run gtktest.py as standalone or imported from activity.py
Line 120: Line 135:
self.set_canvas(self._main_view)
self.set_canvas(self._main_view)
self.show_all()
self.show_all()


= Creating the interface =
= Creating the interface =
We recommend, creating an interface with a ui designer like glade or gazpacho, but understanding the structure is easier using PyGTK.
We recommend creating an interface with a UI designer like glade or gazpacho, but understanding the structure is easier using [[PyGTK]].




Line 211: Line 225:
if __name__ == '__main__':
if __name__ == '__main__':
gtktest(False)
gtktest(False)



=== gtktest.activity/gtktest.glade ===
=== gtktest.activity/gtktest.glade ===
Line 286: Line 299:
</widget>
</widget>
</glade-interface>
</glade-interface>


= Installation & Usage =
= Installation & Usage =
* Run setup.py to create the content bundle
* Run setup.py to create the content bundle
./setup.py dist
* Copy gtktest.xo to your xo/emu (eg. 'scp gtktest.xo olpc@192.168.0.11:/home/olpc')
* Copy gtktest.xo to your xo or emulator (SCP, USB Key, Download, ...)
* Install the bundle with [[Xo-get]]:
* Install the bundle with [[Xo-get]]:
./xo-get.py install gtktest.xo
./xo-get.py install gtktest.xo
* Then you can start the Activity from the Home-Menu
* Then you can start the Activity from the Home-Menu or from xo-get:
./xo-get.py start gtktest.xo
* Remove the Activity:
* Remove the Activity:
./xo-get.py remove gtktest.xo
./xo-get.py remove gtktest.xo


= Troubleshooting =

Application logs are located in /home/olpc/.sugar/default/logs. If you have python compilation errors, the icon for this
tutorial will appear in the run circle and sit there with the "starting..." tag visible on the hover menu forever. You can look in /home/olpc/.sugar/default/logs for a file named after the "activity_name" value in the activity/activity.info file ("org.laptop.gtktest" in the example) to find the actual trouble which caused this behavior. You will have to reboot sugar with &lt;ctrl-alt-erase&gt; in order to remove the spurious icon from the run list.


= Support =
= Support =
Line 305: Line 323:


= Version Information =
= Version Information =
Created: January 2008, Vienna
Tutorials started by [[User:Crazy-chris|crazy-chris]] and [[User:Jaume|Jaume]]: January 2008, Vienna


= References =
* SVG Cow Icon: [http://webcvs.freedesktop.org/svg-icons/lila/gnome/scalable/misc/larry.svg?view=log]
* More SVG Icons: [http://webcvs.freedesktop.org/svg-icons/lila/gnome/scalable/]

* [http://www.pygtk.org/ PyGTK]
** Reference: [http://www.pygtk.org/docs/pygtk/index.html]
** Tutorials: [http://www.moeraki.com/pygtktutorial/pygtk2tutorial/index.html]


* [http://glade.gnome.org/ Glade]
'''Contributors'''
* [http://gazpacho.sicem.biz/ Gazpacho]
* [[User:Crazy-chris]] ([http://www.olpcaustria.org OLPC Austria])
* [[User:Jaume]] ([http://www.olpcaustria.org OLPC Austria])
* ...




[[Category:HowTo]]
Last update: [[User:Crazy-chris|Crazy-chris]] 12:49, 17 January 2008 (EST)
[[Category:Learning]]
[[Category:Activities]]
[[Category:Python]]
[[Category:Developers]]
[[Category:Sugar]]
[[Category:Software development]]

Latest revision as of 15:25, 3 November 2010

  english | españolCopy "{{subst:requesttranslation}}" to 한국어 HowTo [ID# 248433]  +/-  


Welcome! This is a simple tutorial for
creating Activities using PyGTK.


Activity-gtktest.png

About PyGTK

PyGTK is a framework to create a user interface with python. It's quick, easy and very well documented.


Getting started & download

Please start with these first steps:

  1. Make yourself familiar with PyGTK and write few demo applications
  2. Use Glade (or Gazpacho) to design an user interface, and use that in an application. This step is optional, but recommended.

Save the tutorial in your hard disk (here)

At this point we assume that you made at least one "hello-world" application with pygtk :)

The source code from these examples are downloadable here:

Basic Activity Structure

This is a quite minimal list of files and directories for an Activity. You can use this code as a blueprint for your projects, basically changing gtktest to your Activity's name.


gtktest.activity/

This is the Activity's base directory.


gtktest.activity/MANIFEST

This text-file contains the structure of the Activity automatically created by setup.py. In our example:

MANIFEST
setup.py
activity/activity-gtktest.svg
activity/activity.info
activity.py
gtktest.py

gtktest.activity/setup.py

The basic version of setup.py looks like this:

#!/usr/bin/env python
from sugar.activity import bundlebuilder
bundlebuilder.start()

However, here is a more advanced one which also works in a limited fashion on machines where the Sugar environment is not present.

#!/usr/bin/env python
try:
	from sugar.activity import bundlebuilder
	bundlebuilder.start()
except ImportError:
	import os
	os.system("find ./ | sed 's,^./,gtktest.activity/,g' > MANIFEST")
	os.system('rm gtktest.xo')
	os.chdir('..')
	os.system('zip -r gtktest.xo gtktest.activity')
	os.system('mv gtktest.xo ./gtktest.activity')
	os.chdir('gtktest.activity')

gtktest.activity/activity/

This directory contains information for sugar. fds fdg

gtktest.activity/activity/activity-gtktest.svg

A .svg image for our Activity (svg's @ freedesktop.org).


gtktest.activity/activity/activity.info

This file contains information for sugar about our Activity.

[Activity]
name = gtktest
service_name = org.laptop.gtktest
class = activity.gtktestActivity
icon = activity-gtktest
activity_version = 1
show_launcher = yes

gtktest.activity/activity.py

This file is the core of the Activity, which loads the toolbar and window, attaches a GTK Widget to itself, and imports the Activity's source code source code from gtktest.py. This structure has a few advantages:

  1. No need to change activity.py for any code updates
  2. Run gtktest.py as standalone or imported from activity.py
# Load GTK
import gtk

# Load our own source code from gtktest.py
# There you can find the main class gtktest()
from gtktest import gtktest

# Load sugar libraries
from sugar.activity import activity  

class gtktestActivity(activity.Activity):
	def __init__(self, handle):
		activity.Activity.__init__(self, handle)
		self._name = handle

		# Set title for our Activity
		self.set_title('gtk test')

		# Attach sugar toolbox (Share, ...)
		toolbox = activity.ActivityToolbox(self)
		self.set_toolbox(toolbox)
		toolbox.show()

		# Create the main container
		self._main_view = gtk.VBox()

		# Import our class gtktest():

		# Step 1: Load class, which creates gtktest.widget
		self.gtktest = gtktest()

		# Step 2: Remove the widget's parent
		if self.gtktest.widget.parent:
			self.gtktest.widget.parent.remove(self.gtktest.widget)
 
		# Step 3: We attach that widget to our window
		self._main_view.pack_start(self.gtktest.widget)

		# Display everything
		self.gtktest.widget.show()
		self._main_view.show()
		self.set_canvas(self._main_view)
		self.show_all()

Creating the interface

We recommend creating an interface with a UI designer like glade or gazpacho, but understanding the structure is easier using PyGTK.


using PyGTK

We only need to add one file: gtktest.py. Download full example: gtktest.xo


gtktest.activity/gtktest.py

This is the source code of the Activity.

#! /usr/bin/env python

# Pango is a library for rendering internationalized texts
import pango

import gtk

# We don't yet need glade
# import gtk.glade

class gtktest:
	def __init__(self):
		# Create a GTK Label
		label = gtk.Label("Hello World")

		# self.widget will be attached to the Activity
		# This can be any GTK widget except a window
		self.widget = label


using Glade

Example: 3 Buttons and one label. Download Full Example: gtktest-glade.xo

Glade is a User Interface Designer, with it you can rapidly design user interfaces and use them with PyGTK (Getting started). In our example, the glade xml is saved in gtktest.glade.

gtktest.activity/gtktest.py

#! /usr/bin/env python
# Pango is a library for rendering internationalized texts
import pango

import gtk
import gtk.glade

class gtktest:
	def __init__(self, runaslib=True):
		# Load Glade XML
		self.xml = gtk.glade.XML("gtktest.glade")
		
		# Get Window
		self.w = self.xml.get_widget('window1')
		self.w.connect("delete_event", gtk.main_quit)
		
		# Get Windows child
		self.w_child = self.w.get_child()
		
		# Get our Label
		self.label = self.xml.get_widget('label1')
		
		# Connect functions to Buttons
		b1 = self.xml.get_widget('quitButton')
		b1.connect('clicked', self.on_btn_quit)

		b2 = self.xml.get_widget('helloButton')
		b2.connect('clicked', self.on_btn_hello)

		b3 = self.xml.get_widget('cleanButton')
		b3.connect('clicked', self.on_btn_clean)

		# self.widget will be attached to the Activity
		# This can be any GTK widget except a window
		self.widget = self.w_child

		if not runaslib:
			self.w.show_all()
			gtk.main()

	def on_btn_hello(self, *args):
		self.label.set_markup("Hello\nWorld!")

	def on_btn_clean(self, *args):
		self.label.set_markup("Hello")

	def on_btn_quit(self, *args):
		gtk.main_quit()
				
if __name__ == '__main__':
	gtktest(False)

gtktest.activity/gtktest.glade

This file is the XML of the interface, created using Glade:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<glade-interface>
  <widget class="GtkWindow" id="window1">
    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
    <child>
      <widget class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
        <child>
          <widget class="GtkLabel" id="label1">
            <property name="height_request">160</property>
            <property name="visible">True</property>
            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
            <property name="label" translatable="yes"><span font_desc="40">Hello</span></property>
            <property name="use_markup">True</property>
          </widget>
        </child>
        <child>
          <widget class="GtkHButtonBox" id="hbuttonbox1">
            <property name="visible">True</property>
            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
            <property name="border_width">10</property>
            <property name="spacing">10</property>
            <child>
              <widget class="GtkButton" id="helloButton">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                <property name="label" translatable="yes">Who?</property>
                <property name="response_id">0</property>
              </widget>
            </child>
            <child>
              <widget class="GtkButton" id="cleanButton">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                <property name="label" translatable="yes">Clean Up!</property>
                <property name="response_id">0</property>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="quitButton">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                <property name="label" translatable="yes">gtk-quit</property>
                <property name="use_stock">True</property>
                <property name="response_id">0</property>
              </widget>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>

Installation & Usage

  • Run setup.py to create the content bundle
./setup.py dist
  • Copy gtktest.xo to your xo or emulator (SCP, USB Key, Download, ...)
  • Install the bundle with Xo-get:
./xo-get.py install gtktest.xo
  • Then you can start the Activity from the Home-Menu or from xo-get:
./xo-get.py start gtktest.xo
  • Remove the Activity:
./xo-get.py remove gtktest.xo

Troubleshooting

Application logs are located in /home/olpc/.sugar/default/logs. If you have python compilation errors, the icon for this tutorial will appear in the run circle and sit there with the "starting..." tag visible on the hover menu forever. You can look in /home/olpc/.sugar/default/logs for a file named after the "activity_name" value in the activity/activity.info file ("org.laptop.gtktest" in the example) to find the actual trouble which caused this behavior. You will have to reboot sugar with <ctrl-alt-erase> in order to remove the spurious icon from the run list.

Support

Questions, feedback, or whatever: Talk:PyGTK/Hello_World_Tutorial

Feel free to edit this page and to add yourself to the contributors list.


Version Information

Tutorials started by crazy-chris and Jaume: January 2008, Vienna


References

  • SVG Cow Icon: [1]
  • More SVG Icons: [2]