个人工具

“UbuntuHelp:UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon”的版本间的差异

来自Ubuntu中文

跳转至: 导航, 搜索
(新页面: {{From|https://help.ubuntu.com/community/UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon}} {{Languages|UbuntuHelp:UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon}}...)
 
 
(未显示同一用户的4个中间版本)
第1行: 第1行:
 
{{From|https://help.ubuntu.com/community/UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon}}
 
{{From|https://help.ubuntu.com/community/UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon}}
 
{{Languages|UbuntuHelp:UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon}}
 
{{Languages|UbuntuHelp:UMEGuide/ApplicationDevelopment/GladeWithPythonForUMEHildon}}
 +
#title Glade with Python for UME/Hildon
 +
<<Include(Tag/ContentCleanup)>>
 +
<<Include(Tag/StyleCleanup)>>
 +
<<Include(Tag/NeedsExpansion)>>
 
=== Purpose ===
 
=== Purpose ===
 
 
This wiki page explains how to import an application's user interface that was made with Glade into Python in order to make a UME/Hildon application. In particular, it covers:
 
This wiki page explains how to import an application's user interface that was made with Glade into Python in order to make a UME/Hildon application. In particular, it covers:
 
 
* How to import a Glade user interface definition file into Python
 
* How to import a Glade user interface definition file into Python
 
* How to access objects defined in Glade and give them local Python names
 
* How to access objects defined in Glade and give them local Python names
 
* How to reparent Glade widgets to the required Python Hildon Window
 
* How to reparent Glade widgets to the required Python Hildon Window
 
* How to get a GTK Menu defined in Glade and set it as the Hildon Program menu in Python
 
* How to get a GTK Menu defined in Glade and set it as the Hildon Program menu in Python
 
 
'''Terminology''': What's "reparenting"? The top level window in a UME application is - by definition - a Hildon Window. However, Glade can only create a GTK Window, not the Hildon Window you need. (When using Glade, you need a GTK Window as a top-level widget so that you can add other child widgets to it). To deal with this mismatch, you create a real Hildon Window in your Python and then "reparent" the GTK Window's direct children to it.
 
'''Terminology''': What's "reparenting"? The top level window in a UME application is - by definition - a Hildon Window. However, Glade can only create a GTK Window, not the Hildon Window you need. (When using Glade, you need a GTK Window as a top-level widget so that you can add other child widgets to it). To deal with this mismatch, you create a real Hildon Window in your Python and then "reparent" the GTK Window's direct children to it.
 
 
=== Prerequisites ===
 
=== Prerequisites ===
 
 
* Glade
 
* Glade
 
* A UME development/build/run environment
 
* A UME development/build/run environment
 
* Understanding of the files and directories required by a UME Desktop Python application -- see  
 
* Understanding of the files and directories required by a UME Desktop Python application -- see  
 
[[UbuntuHelp:UMEGuide/ApplicationDevelopment/AnatomyOfUMEPythonApplication| Files and Directories for Adding a Python Application to UME]]
 
[[UbuntuHelp:UMEGuide/ApplicationDevelopment/AnatomyOfUMEPythonApplication| Files and Directories for Adding a Python Application to UME]]
 
 
* Basic Python knowledge
 
* Basic Python knowledge
 
 
=== Packages ===
 
=== Packages ===
 
 
You will need the following packages installed in the UME target:
 
You will need the following packages installed in the UME target:
 
* python-gtk2
 
* python-gtk2
 
* python-hildon-1.2
 
* python-hildon-1.2
 
* python-glade2
 
* python-glade2
 
 
You can install each by entering the target UME root directory (the target chroot when working from Image-Creator) and executing the usual <code><nowiki>apt-get install (package name)</nowiki></code> command.
 
You can install each by entering the target UME root directory (the target chroot when working from Image-Creator) and executing the usual <code><nowiki>apt-get install (package name)</nowiki></code> command.
 
 
 
=== Using Glade ===
 
=== Using Glade ===
 
This how-to assumes basic knowledge of how to use Glade. However, even if you've never used it before, rest assured that it's quite easy.  
 
This how-to assumes basic knowledge of how to use Glade. However, even if you've never used it before, rest assured that it's quite easy.  
 
 
Glade is a graphical tool for creating a GTK user interface by dragging widgets onto a canvas or into other widgets (in which case they become children) and then optionally selecting widgets and modifying their properties. The result is an XML file with the ''.glade'' extension that contains a description of the user interface that can be imported into various languages, including Python. After importing the .glade file, you can access the widgets using the names you gave them in Glade and then use them programmatically.  
 
Glade is a graphical tool for creating a GTK user interface by dragging widgets onto a canvas or into other widgets (in which case they become children) and then optionally selecting widgets and modifying their properties. The result is an XML file with the ''.glade'' extension that contains a description of the user interface that can be imported into various languages, including Python. After importing the .glade file, you can access the widgets using the names you gave them in Glade and then use them programmatically.  
 
 
As noted, one important point is how to deal with the fact that Glade cannot create a Hildon Window. It can only create a GTK Window, and indeed it requires one as a parent for most other widgets (but not menus). So, in Glade, you create the GTK Window and add widgets to it, then, in your Python you "reparent" the GTK Window's child widgets to your real Hildon Window. To minimize reparenting, this example program's root window has only one child, a GTK VBox widget, which in turn contains child widgets. So, this VBox must be reparented from the GTK Window to a Hildon Window.
 
As noted, one important point is how to deal with the fact that Glade cannot create a Hildon Window. It can only create a GTK Window, and indeed it requires one as a parent for most other widgets (but not menus). So, in Glade, you create the GTK Window and add widgets to it, then, in your Python you "reparent" the GTK Window's child widgets to your real Hildon Window. To minimize reparenting, this example program's root window has only one child, a GTK VBox widget, which in turn contains child widgets. So, this VBox must be reparented from the GTK Window to a Hildon Window.
 
 
Let's take a look at these steps in a little more detail, but first let's review the Python program's basic structure.
 
Let's take a look at these steps in a little more detail, but first let's review the Python program's basic structure.
 
 
=== This Python program's structure ===
 
=== This Python program's structure ===
'''Note''': Please see [[main.py main.py source]] at the end of this page.
+
'''Note''': Please see [[UbuntuHelp:[main.py|main.py source]]] at the end of this page.
 
+
 
This is a simple Python program.  
 
This is a simple Python program.  
 
 
Among the usual imports at the top is: ''import gtk.glade'', which is required to import the .glade file.
 
Among the usual imports at the top is: ''import gtk.glade'', which is required to import the .glade file.
 
 
The program has one class, <code><nowiki>GladeTestApp</nowiki></code>, whose constructor creates the Hildon Program and Hildon Window, imports the .glade file, assigns Glade objects local names, reparents a widget, sets the Hildon program menu from a Glade-defined menu, sets up signal handlers for user events, and other things.  
 
The program has one class, <code><nowiki>GladeTestApp</nowiki></code>, whose constructor creates the Hildon Program and Hildon Window, imports the .glade file, assigns Glade objects local names, reparents a widget, sets the Hildon program menu from a Glade-defined menu, sets up signal handlers for user events, and other things.  
 
 
The class is instantiated as an object named <code><nowiki>app</nowiki></code>, and it's <code><nowiki>run()</nowiki></code> method is executed.  
 
The class is instantiated as an object named <code><nowiki>app</nowiki></code>, and it's <code><nowiki>run()</nowiki></code> method is executed.  
 
 
Let's start by examining how the constructor creates the Hildon Program and Hildon Window.
 
Let's start by examining how the constructor creates the Hildon Program and Hildon Window.
 
 
=== Creating the Hildon Program and Hildon Window ===
 
=== Creating the Hildon Program and Hildon Window ===
 
 
Here's the top of the <code><nowiki>GladeTestApp</nowiki></code> class, showing the beginning of its constructor.
 
Here's the top of the <code><nowiki>GladeTestApp</nowiki></code> class, showing the beginning of its constructor.
 
 
<pre><nowiki>
 
<pre><nowiki>
 
class GladeTestApp():
 
class GladeTestApp():
"""pygtk-glade-hildon demo project"""
+
    """pygtk-glade-hildon demo project"""
  
def <u>init</u>(self):
+
    def __init__(self):
  
#make the hildon program
+
        #make the hildon program
self.program = hildon.Program()
+
        self.program = hildon.Program()
self.program.<u>init</u>()
+
        self.program.__init__()
 
+
       
#make the hildon window and add to program
+
        #make the hildon window and add to program
self.window = hildon.Window()
+
        self.window = hildon.Window()
self.window.set_title("PyGlade")
+
        self.window.set_title("PyGlade")
self.program.add_window(self.window
+
        self.program.add_window(self.window
 
</nowiki></pre>
 
</nowiki></pre>
 
 
As you can see, the Hildon Program is created and assigned to <code><nowiki>self.program</nowiki></code>. And, the Hildon Window is created and assigned to <code><nowiki>self.window</nowiki></code>. Pretty straightforward.  
 
As you can see, the Hildon Program is created and assigned to <code><nowiki>self.program</nowiki></code>. And, the Hildon Window is created and assigned to <code><nowiki>self.window</nowiki></code>. Pretty straightforward.  
 
 
Next, we'll import the .glade file.
 
Next, we'll import the .glade file.
 
 
=== Importing the .glade file ===
 
=== Importing the .glade file ===
 
The .glade file is imported inside <code><nowiki>GladeTestApp</nowiki></code>'s constructor. The code looks like this:
 
The .glade file is imported inside <code><nowiki>GladeTestApp</nowiki></code>'s constructor. The code looks like this:
 
<pre><nowiki>
 
<pre><nowiki>
self.glade_file = "pygladeui.glade"
+
        self.glade_file = "pygladeui.glade"
self.wTree=gtk.glade.XML(self.glade_file)
+
        self.wTree=gtk.glade.XML(self.glade_file)
 
</nowiki></pre>
 
</nowiki></pre>
 
 
The first line defines a variable (<code><nowiki>self.glade_file</nowiki></code>) and assigns it the file name of the .glade file, in this case <code><nowiki>pygladeui.glade</nowiki></code>.  
 
The first line defines a variable (<code><nowiki>self.glade_file</nowiki></code>) and assigns it the file name of the .glade file, in this case <code><nowiki>pygladeui.glade</nowiki></code>.  
 
 
The second line actually imports all user interface objects from the specified .glade file into a new variable named <code><nowiki>self.wTree</nowiki></code>.  
 
The second line actually imports all user interface objects from the specified .glade file into a new variable named <code><nowiki>self.wTree</nowiki></code>.  
 
 
Now, all the objects defined in the .glade file can be retrieved from <code><nowiki>self.wTree</nowiki></code> and can be assigned local names for programmatic use. They are retrieved using the names they were given (or assigned by default) when using Glade, as shown next.
 
Now, all the objects defined in the .glade file can be retrieved from <code><nowiki>self.wTree</nowiki></code> and can be assigned local names for programmatic use. They are retrieved using the names they were given (or assigned by default) when using Glade, as shown next.
 
 
=== Reparenting to Hildon Window ===
 
=== Reparenting to Hildon Window ===
 
 
As noted, the GTK window made with Glade contains a GTK VBox widget that contains all other application widgets (except for the menu, discussed below). When making this VBox widget with Glade, I gave it the following name: ''vbox1''. (The widget's name is viewed/set in Glade by selecting it and looking at its "properties" in the Properties window.)
 
As noted, the GTK window made with Glade contains a GTK VBox widget that contains all other application widgets (except for the menu, discussed below). When making this VBox widget with Glade, I gave it the following name: ''vbox1''. (The widget's name is viewed/set in Glade by selecting it and looking at its "properties" in the Properties window.)
 
 
Here's the Python code that fetches the VBox from the imported glade file:
 
Here's the Python code that fetches the VBox from the imported glade file:
 
 
<pre><nowiki>
 
<pre><nowiki>
#reparent the vbox1 from glade to self.window
+
        #reparent the vbox1 from glade to self.window
self.vbox1 = self.wTree.get_widget("vbox1")
+
        self.vbox1 = self.wTree.get_widget("vbox1")
self.reparent_loc(self.vbox1, self.window)
+
        self.reparent_loc(self.vbox1, self.window)
 
</nowiki></pre>
 
</nowiki></pre>
 
 
The first non-comment code line gets the specified GTK VBox and assigns it to the <code><nowiki>self.vbox1</nowiki></code> variable.  
 
The first non-comment code line gets the specified GTK VBox and assigns it to the <code><nowiki>self.vbox1</nowiki></code> variable.  
 
 
The second reparents the VBox from the GTK window made in Glade to the Hildon Window made in Python that's named <code><nowiki>self.window</nowiki></code> with the <code><nowiki>reparent_loc()</nowiki></code> function.
 
The second reparents the VBox from the GTK window made in Glade to the Hildon Window made in Python that's named <code><nowiki>self.window</nowiki></code> with the <code><nowiki>reparent_loc()</nowiki></code> function.
 
 
That's it for reparenting! Let's take a look at importing the GTK menu made in Glade and setting it as the application's Hildon menu.
 
That's it for reparenting! Let's take a look at importing the GTK menu made in Glade and setting it as the application's Hildon menu.
 
 
=== Getting the menu and making it a Hildon Menu ===
 
=== Getting the menu and making it a Hildon Menu ===
 
In Hildon, you create a GTK menu and add it to the Hildon Program with the <code><nowiki>set_common_menu(GTK.menu)</nowiki></code> function, as mentioned previously.  
 
In Hildon, you create a GTK menu and add it to the Hildon Program with the <code><nowiki>set_common_menu(GTK.menu)</nowiki></code> function, as mentioned previously.  
 
 
The following Python code shows how to get the imported the GTK menu that's named <code><nowiki>menu1</nowiki></code>, assign it to <code><nowiki>self.menuGlade</nowiki></code>, and then set the Hildon Program to use this as its common menu.  
 
The following Python code shows how to get the imported the GTK menu that's named <code><nowiki>menu1</nowiki></code>, assign it to <code><nowiki>self.menuGlade</nowiki></code>, and then set the Hildon Program to use this as its common menu.  
 
 
 
<pre><nowiki>
 
<pre><nowiki>
#get menu from glade and reparent as common menu in hildon program
+
        #get menu from glade and reparent as common menu in hildon program
self.menuGlade = self.wTree.get_widget("menu1")
+
        self.menuGlade = self.wTree.get_widget("menu1")
self.program.set_common_menu(self.menuGlade)   
+
        self.program.set_common_menu(self.menuGlade)   
 
</nowiki></pre>
 
</nowiki></pre>
 
=== Source ===
 
=== Source ===
 
 
==== main.py ====
 
==== main.py ====
 
 
<pre><nowiki>
 
<pre><nowiki>
 
import pygtk
 
import pygtk
第130行: 第92行:
  
 
class GladeTestApp():
 
class GladeTestApp():
"""pygtk-glade-hildon demo project"""
+
    """pygtk-glade-hildon demo project"""
  
def <u>init</u>(self):
+
    def __init__(self):
  
#make the hildon program
+
        #make the hildon program
self.program = hildon.Program()
+
        self.program = hildon.Program()
self.program.<u>init</u>()
+
        self.program.__init__()
 +
       
 +
        #make the hildon window and add to program
 +
        self.window = hildon.Window()
 +
        self.window.set_title("PyGlade")
 +
        self.program.add_window(self.window)
 +
       
 +
        #receive signal to close window from framework close button 
 +
        if (self.window):
 +
            self.window.connect("destroy", gtk.main_quit)
 +
       
 +
        #import the glade file and assign to self.wTree
 +
        self.glade_file = "pygladeui.glade"
 +
        self.wTree = gtk.glade.XML(self.glade_file)
 +
       
 +
        #reparent the vbox1 from glade to self.window
 +
        self.vbox1 = self.wTree.get_widget("vbox1")
 +
        self.reparent_loc(self.vbox1, self.window)
 +
       
 +
        #get menu from glade and reparent as common menu in hildon program
 +
        self.menuGlade = self.wTree.get_widget("menu1")
 +
        self.program.set_common_menu(self.menuGlade)       
 +
       
 +
        #get quit menu item and connect signal
 +
        self.menuItem_quit = self.wTree.get_widget("quit1")
 +
        self.menuItem_quit.connect("activate", gtk.main_quit)
 +
 
 +
        #get hbox1 in order to modify contents based on user actions
 +
        self.hbox1 = self.wTree.get_widget("hbox1")
  
#make the hildon window and add to program
+
        #get label1 for use   
self.window = hildon.Window()
+
        self.label1 = self.wTree.get_widget("label1")      
self.window.set_title("PyGlade")
+
self.program.add_window(self.window)
+
  
#receive signal to close window from framework close button 
+
        self.controlBar = hildon.Controlbar()
if (self.window):
+
        self.controlBar.set_min(0)
self.window.connect("destroy", gtk.main_quit)
+
        self.controlBar.set_max(50)  
 +
        self.controlBar.set_value(15)
 +
        self.controlBar.connect("value-changed", self.control_changed, self.label1)
 +
       
 +
        self.menuItem_controlBar = self.wTree.get_widget("controlBar")
 +
        self.menuItem_controlBar.connect("activate", self.controlBar_pressed, self.hbox1, self.controlBar, self.label1)
  
#import the glade file and assign to self.wTree
+
        self.dateEditor = hildon.DateEditor()
self.glade_file = "pygladeui.glade"
+
        self.dateEditor.set_year(2006)
self.wTree = gtk.glade.XML(self.glade_file)
+
        self.dateEditor.set_month(4)
 +
        self.dateEditor.set_day(20) 
 +
     
 +
        self.menuItem_dateEditor = self.wTree.get_widget("dateEditor")
 +
        self.menuItem_dateEditor.connect("activate", self.dateEditor_pressed, self.hbox1, self.dateEditor, self.label1)       
 +
       
 +
        #get button1 and connect a signal handler
 +
        self.button1 = self.wTree.get_widget("button1")
 +
        if (self.button1):
 +
            self.button1.connect("pressed", self.button1_pressed, self.label1)
 +
       
 +
        #destroy the gtk window imported from glade
 +
        self.gtkWindow = self.wTree.get_widget("window1")
 +
        self.gtkWindow.destroy()
 +
       
 +
        #display everything
 +
        self.window.show_all()
  
#reparent the vbox1 from glade to self.window
+
    def run(self):
self.vbox1 = self.wTree.get_widget("vbox1")
+
        gtk.main()
self.reparent_loc(self.vbox1, self.window)
+
 
+
#get menu from glade and reparent as common menu in hildon program
+
self.menuGlade = self.wTree.get_widget("menu1")
+
self.program.set_common_menu(self.menuGlade)       
+
 
+
#get quit menu item and connect signal
+
self.menuItem_quit = self.wTree.get_widget("quit1")
+
self.menuItem_quit.connect("activate", gtk.main_quit)
+
 
+
#get hbox1 in order to modify contents based on user actions
+
self.hbox1 = self.wTree.get_widget("hbox1")
+
 
+
#get label1 for use   
+
self.label1 = self.wTree.get_widget("label1")       
+
 
+
self.controlBar = hildon.Controlbar()
+
self.controlBar.set_min(0)
+
self.controlBar.set_max(50)
+
self.controlBar.set_value(15)
+
self.controlBar.connect("value-changed", self.control_changed, self.label1)
+
 
+
self.menuItem_controlBar = self.wTree.get_widget("controlBar")
+
self.menuItem_controlBar.connect("activate", self.controlBar_pressed, self.hbox1, self.controlBar, self.label1)
+
 
+
self.dateEditor = hildon.DateEditor()
+
self.dateEditor.set_year(2006)
+
self.dateEditor.set_month(4)
+
self.dateEditor.set_day(20) 
+
 
+
self.menuItem_dateEditor = self.wTree.get_widget("dateEditor")
+
self.menuItem_dateEditor.connect("activate", self.dateEditor_pressed, self.hbox1, self.dateEditor, self.label1)       
+
 
+
#get button1 and connect a signal handler
+
self.button1 = self.wTree.get_widget("button1")
+
if (self.button1):
+
self.button1.connect("pressed", self.button1_pressed, self.label1)
+
 
+
#destroy the gtk window imported from glade
+
self.gtkWindow = self.wTree.get_widget("window1")
+
self.gtkWindow.destroy()
+
 
+
#display everything
+
self.window.show_all()
+
 
+
def run(self):
+
gtk.main()
+
  
 
# signal handlers
 
# signal handlers
 +
   
 +
    def menuItem_quit1_pressed(self, widget):
 +
        gtk.main_quit
  
def menuItem_quit1_pressed(self, widget):
+
    def button1_pressed(self, widget, label):
gtk.main_quit
+
        label.set_label("new label")     
 
+
   
def button1_pressed(self, widget, label):
+
label.set_label("new label")     
+
 
+
 
# controlBar
 
# controlBar
  
def controlBar_pressed(self, widget, hbox, controlBar, label):
+
    def controlBar_pressed(self, widget, hbox, controlBar, label):
self.dechild_hbox(hbox)
+
        self.dechild_hbox(hbox)
hbox.add(controlBar)
+
        hbox.add(controlBar)
controlBar.show()
+
        controlBar.show()
label.set_text("ControlBar")
+
        label.set_text("ControlBar")
  
def control_changed(self, widget, label):  
+
    def control_changed(self, widget, label):  
label.set_text(" %s of %s" % (widget.get_value(), widget.get_max()))
+
        label.set_text(" %s of %s" % (widget.get_value(), widget.get_max()))
  
 
# dateEditor
 
# dateEditor
  
def dateEditor_pressed(self, widget, hbox, dateEditor, label):
+
    def dateEditor_pressed(self, widget, hbox, dateEditor, label):
self.dechild_hbox(hbox)
+
        self.dechild_hbox(hbox)
hbox.add(dateEditor)
+
        hbox.add(dateEditor)
label.set_text("DateEditor")
+
        label.set_text("DateEditor")
dateEditor.show()
+
        dateEditor.show()
  
 
#utility
 
#utility
  
def dechild_hbox(self, hbox_widgets):
+
    def dechild_hbox(self, hbox_widgets):
children = hbox_widgets.get_children()
+
        children = hbox_widgets.get_children()
for child in children:
+
        for child in children:
hbox_widgets.remove(child)
+
            hbox_widgets.remove(child)
  
def reparent_loc(self, widget, newParent):
+
    def reparent_loc(self, widget, newParent):
widget.reparent(newParent)
+
        widget.reparent(newParent)
  
if <u>name</u> == "<u>main</u>":
+
if __name__ == "__main__":
app = GladeTestApp()
+
    app = GladeTestApp()
app.run()
+
    app.run()
 
</nowiki></pre>
 
</nowiki></pre>
 
 
==== Makefile ====
 
==== Makefile ====
 
<pre><nowiki>
 
<pre><nowiki>
第265行: 第226行:
 
</nowiki></pre>
 
</nowiki></pre>
 
re.
 
re.
 +
----
 +
[[category:CategoryProgramming]]
  
 
[[category:UbuntuHelp]]
 
[[category:UbuntuHelp]]

2009年11月17日 (二) 21:00的最新版本

  1. title Glade with Python for UME/Hildon

<<Include(Tag/ContentCleanup)>> <<Include(Tag/StyleCleanup)>> <<Include(Tag/NeedsExpansion)>>

Purpose

This wiki page explains how to import an application's user interface that was made with Glade into Python in order to make a UME/Hildon application. In particular, it covers:

  • How to import a Glade user interface definition file into Python
  • How to access objects defined in Glade and give them local Python names
  • How to reparent Glade widgets to the required Python Hildon Window
  • How to get a GTK Menu defined in Glade and set it as the Hildon Program menu in Python

Terminology: What's "reparenting"? The top level window in a UME application is - by definition - a Hildon Window. However, Glade can only create a GTK Window, not the Hildon Window you need. (When using Glade, you need a GTK Window as a top-level widget so that you can add other child widgets to it). To deal with this mismatch, you create a real Hildon Window in your Python and then "reparent" the GTK Window's direct children to it.

Prerequisites

  • Glade
  • A UME development/build/run environment
  • Understanding of the files and directories required by a UME Desktop Python application -- see

Files and Directories for Adding a Python Application to UME

  • Basic Python knowledge

Packages

You will need the following packages installed in the UME target:

  • python-gtk2
  • python-hildon-1.2
  • python-glade2

You can install each by entering the target UME root directory (the target chroot when working from Image-Creator) and executing the usual apt-get install (package name) command.

Using Glade

This how-to assumes basic knowledge of how to use Glade. However, even if you've never used it before, rest assured that it's quite easy. Glade is a graphical tool for creating a GTK user interface by dragging widgets onto a canvas or into other widgets (in which case they become children) and then optionally selecting widgets and modifying their properties. The result is an XML file with the .glade extension that contains a description of the user interface that can be imported into various languages, including Python. After importing the .glade file, you can access the widgets using the names you gave them in Glade and then use them programmatically. As noted, one important point is how to deal with the fact that Glade cannot create a Hildon Window. It can only create a GTK Window, and indeed it requires one as a parent for most other widgets (but not menus). So, in Glade, you create the GTK Window and add widgets to it, then, in your Python you "reparent" the GTK Window's child widgets to your real Hildon Window. To minimize reparenting, this example program's root window has only one child, a GTK VBox widget, which in turn contains child widgets. So, this VBox must be reparented from the GTK Window to a Hildon Window. Let's take a look at these steps in a little more detail, but first let's review the Python program's basic structure.

This Python program's structure

Note: Please see [[UbuntuHelp:[main.py|main.py source]]] at the end of this page. This is a simple Python program. Among the usual imports at the top is: import gtk.glade, which is required to import the .glade file. The program has one class, GladeTestApp, whose constructor creates the Hildon Program and Hildon Window, imports the .glade file, assigns Glade objects local names, reparents a widget, sets the Hildon program menu from a Glade-defined menu, sets up signal handlers for user events, and other things. The class is instantiated as an object named app, and it's run() method is executed. Let's start by examining how the constructor creates the Hildon Program and Hildon Window.

Creating the Hildon Program and Hildon Window

Here's the top of the GladeTestApp class, showing the beginning of its constructor.

class GladeTestApp():
    """pygtk-glade-hildon demo project"""

    def __init__(self):

        #make the hildon program
        self.program = hildon.Program()
        self.program.__init__()
        
        #make the hildon window and add to program
        self.window = hildon.Window()
        self.window.set_title("PyGlade")
        self.program.add_window(self.window

As you can see, the Hildon Program is created and assigned to self.program. And, the Hildon Window is created and assigned to self.window. Pretty straightforward. Next, we'll import the .glade file.

Importing the .glade file

The .glade file is imported inside GladeTestApp's constructor. The code looks like this:

        self.glade_file = "pygladeui.glade"
        self.wTree=gtk.glade.XML(self.glade_file)

The first line defines a variable (self.glade_file) and assigns it the file name of the .glade file, in this case pygladeui.glade. The second line actually imports all user interface objects from the specified .glade file into a new variable named self.wTree. Now, all the objects defined in the .glade file can be retrieved from self.wTree and can be assigned local names for programmatic use. They are retrieved using the names they were given (or assigned by default) when using Glade, as shown next.

Reparenting to Hildon Window

As noted, the GTK window made with Glade contains a GTK VBox widget that contains all other application widgets (except for the menu, discussed below). When making this VBox widget with Glade, I gave it the following name: vbox1. (The widget's name is viewed/set in Glade by selecting it and looking at its "properties" in the Properties window.) Here's the Python code that fetches the VBox from the imported glade file:

        #reparent the vbox1 from glade to self.window
        self.vbox1 = self.wTree.get_widget("vbox1")
        self.reparent_loc(self.vbox1, self.window)

The first non-comment code line gets the specified GTK VBox and assigns it to the self.vbox1 variable. The second reparents the VBox from the GTK window made in Glade to the Hildon Window made in Python that's named self.window with the reparent_loc() function. That's it for reparenting! Let's take a look at importing the GTK menu made in Glade and setting it as the application's Hildon menu.

Getting the menu and making it a Hildon Menu

In Hildon, you create a GTK menu and add it to the Hildon Program with the set_common_menu(GTK.menu) function, as mentioned previously. The following Python code shows how to get the imported the GTK menu that's named menu1, assign it to self.menuGlade, and then set the Hildon Program to use this as its common menu.

        #get menu from glade and reparent as common menu in hildon program
        self.menuGlade = self.wTree.get_widget("menu1")
        self.program.set_common_menu(self.menuGlade)  

Source

main.py

import pygtk
import gtk
import hildon
import gtk.glade

class GladeTestApp():
    """pygtk-glade-hildon demo project"""

    def __init__(self):

        #make the hildon program
        self.program = hildon.Program()
        self.program.__init__()
        
        #make the hildon window and add to program
        self.window = hildon.Window()
        self.window.set_title("PyGlade")
        self.program.add_window(self.window)
        
        #receive signal to close window from framework close button  
        if (self.window):
            self.window.connect("destroy", gtk.main_quit)
        
        #import the glade file and assign to self.wTree
        self.glade_file = "pygladeui.glade"
        self.wTree = gtk.glade.XML(self.glade_file)
        
        #reparent the vbox1 from glade to self.window
        self.vbox1 = self.wTree.get_widget("vbox1")
        self.reparent_loc(self.vbox1, self.window)
        
        #get menu from glade and reparent as common menu in hildon program
        self.menuGlade = self.wTree.get_widget("menu1")
        self.program.set_common_menu(self.menuGlade)        
        
        #get quit menu item and connect signal
        self.menuItem_quit = self.wTree.get_widget("quit1")
        self.menuItem_quit.connect("activate", gtk.main_quit)
  
        #get hbox1 in order to modify contents based on user actions
        self.hbox1 = self.wTree.get_widget("hbox1")

        #get label1 for use    
        self.label1 = self.wTree.get_widget("label1")        

        self.controlBar = hildon.Controlbar()
        self.controlBar.set_min(0) 
        self.controlBar.set_max(50) 
        self.controlBar.set_value(15) 
        self.controlBar.connect("value-changed", self.control_changed, self.label1)
        
        self.menuItem_controlBar = self.wTree.get_widget("controlBar")
        self.menuItem_controlBar.connect("activate", self.controlBar_pressed, self.hbox1, self.controlBar, self.label1)

        self.dateEditor = hildon.DateEditor() 
        self.dateEditor.set_year(2006) 
        self.dateEditor.set_month(4) 
        self.dateEditor.set_day(20)  
      
        self.menuItem_dateEditor = self.wTree.get_widget("dateEditor")
        self.menuItem_dateEditor.connect("activate", self.dateEditor_pressed, self.hbox1, self.dateEditor, self.label1)        
        
        #get button1 and connect a signal handler
        self.button1 = self.wTree.get_widget("button1")
        if (self.button1):
            self.button1.connect("pressed", self.button1_pressed, self.label1)
        
        #destroy the gtk window imported from glade
        self.gtkWindow = self.wTree.get_widget("window1")
        self.gtkWindow.destroy()
        
        #display everything
        self.window.show_all()

    def run(self):
        gtk.main()

# signal handlers
    
    def menuItem_quit1_pressed(self, widget):
        gtk.main_quit 

    def button1_pressed(self, widget, label):
        label.set_label("new label")     
    
# controlBar

    def controlBar_pressed(self, widget, hbox, controlBar, label):
        self.dechild_hbox(hbox)
        hbox.add(controlBar)
        controlBar.show()
        label.set_text("ControlBar")

    def control_changed(self, widget, label): 
        label.set_text(" %s of %s" % (widget.get_value(), widget.get_max()))

# dateEditor

    def dateEditor_pressed(self, widget, hbox, dateEditor, label):
        self.dechild_hbox(hbox)
        hbox.add(dateEditor)
        label.set_text("DateEditor")
        dateEditor.show()

#utility

    def dechild_hbox(self, hbox_widgets):
        children = hbox_widgets.get_children()
        for child in children:
            hbox_widgets.remove(child)

    def reparent_loc(self, widget, newParent):
        widget.reparent(newParent)

if __name__ == "__main__":
    app = GladeTestApp()
    app.run()

Makefile

BINDIR = ${DESTDIR}/usr/bin/
APPDIR = ${DESTDIR}/usr/share/pyglade
all: 
install:
	@mkdir -p ${BINDIR}
	@mkdir -p ${APPDIR}
	@install -m 755 -D main.py ${APPDIR}/main.py
	@install -m 755 -D pygladeui.glade ${APPDIR}/pygladeui.glade
	@install -m 755 -D executable.txt ${BINDIR}/pyglade
	@install -m 755 -D desktop.txt ${DESTDIR}/usr/share/applications/pyglade.desktop
	@install -m 755 -D pyglade_26.png ${DESTDIR}/usr/share/icons/hicolor/22x22/apps/pyglade_26.png

clean:
	@rm -f ${APPDIR}/main.py
	@rm -f ${APPDIR}/pygladeui.glade
	@rm -f ${BINDIR}/pyglade
	@rm -f ${DESTDIR}/usr/share/applications/pyglade.desktop
	@rm -f ${DESTDIR}/usr/share/icons/${THEME}/22x22/apps/pyglade_26.png

re.