Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added section on sub-classing GObject

  • Loading branch information...
commit b393212f2c88fd0af4a3c72442ea889143725653 1 parent 34726da
@xapantu xapantu authored sebp committed
Showing with 338 additions and 0 deletions.
  1. +338 −0 source/objects.txt
View
338 source/objects.txt
@@ -0,0 +1,338 @@
+.. _objects:
+
+Objects
+=======
+
+GObject is the fundamental type providing the common attributes and methods
+for all object types in GTK+, Pango and other libraries based on GObject.
+The :class:`GObject.GObject` class provides methods for object construction and destruction,
+property access methods, and signal support.
+
+This section will introduce some important aspects about the GObject
+implementation in python.
+
+Inherit from GObject.Object
+---------------------------
+
+A native GObject is accessible via :class:`GObject.GObject`. It is rarely intanciated
+directly, we generally use inherited class. A :class:`Gtk.Widget` is an inherited class
+of a :class:`GObject.GObject`. It may be interesting to make an inherited class to create
+a new widget, like a settings dialog.
+
+To inherit from :class:`GObject.GObject`, you must call :meth:`GObject.GObject.__init__`
+in your constructor (if the class inherits from :class:`Gtk.Button`, it must
+call :func:`Gtk.Button.__init__` for instance), like in the example below:
+
+.. code-block:: python
+
+ from gi.repository import GObject
+
+ class MyObject(GObject.GObject):
+
+ def __init__(self):
+ GObject.GObject.__init__(self)
+
+
+Signals
+-------
+
+Signals connect arbitrary application-specific events with any number of listeners.
+For example, in GTK+, every user event (keystroke or mouse move) is received
+from the X server and generates a GTK+ event under the form of a signal emission
+on a given object instance.
+
+Each signal is registered in the type system together with the type on which it
+can be emitted: users of the type are said to connect to the signal on a given
+type instance when they register a function to be invoked upon the signal
+emission. Users can also emit the signal by themselves or stop the emission of
+the signal from within one of the functions connected to the signal.
+
+Receive signals
+^^^^^^^^^^^^^^^
+
+See :ref:`signals`
+
+Create new signals
+^^^^^^^^^^^^^^^^^^
+
+New signals can be created by adding them to
+:attr:`GObject.GObject.__gsignals__`, a dictionary:
+
+When a new signal is created, a method handler can also be defined, it will be
+called each time the signal is emitted. It is called do_signal_name.
+
+.. code-block:: python
+
+ class MyObject(GObject.GObject):
+ __gsignals__ = {
+ 'my_signal': (GObject.SIGNAL_RUN_FIRST, None,
+ (int,))
+ }
+
+ def do_my_signal(self, arg):
+ print "class method for `my_signal' called with argument", arg
+
+:const:`GObject.SIGNAL_RUN_FIRST` indicates ths signal will invoke the object method
+handler (:meth:`do_my_signal` here) in the first emission stage. Alternatives are
+:const:`GObject.SIGNAL_RUN_LAST` (the method handler will be invoked in the third
+emission stage) and :const:`GObject.SIGNAL_RUN_CLEANUP` (invoke the method handler in the
+last emission stage).
+
+The second part, ``None``, indicates the return type of the signal,
+usually ``None``.
+
+``(int,)`` indicates the signal arguments, here, the signal will only
+take one argument, whose type is int. This argument type list must end with a
+comma.
+
+Signals can be emitted using :meth:`GObject.GObject.emit`:
+
+.. code-block:: python
+
+ my_obj.emit("my_signal", 42) # emit the signal "my_signal", with the
+ # argument 42
+
+Properties
+----------
+One of GObject's nice features is its generic get/set mechanism for object
+properties. Each class inherited from :class:`GObject.GObject` can define new
+properties. Each property as a type which never changes (e.g. str, float,
+int...). For instance, they are used for :class:`Gtk.Button` where there is a
+"label" property which contains the text of the button.
+
+Use existing properties
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The class :class:`GObject.GObject` provides several useful functions to manage
+existing properties, :func:`GObject.GObject.get_property` and :func:`GObject.GObject.set_property`.
+
+Some properties also have functions dedicated to them, called getter and setter.
+For the property "label" of a button, there are two functions to get and set
+them, :func:`Gtk.Button.get_label` and :func:`Gtk.Button.set_label`.
+
+Create new properties
+^^^^^^^^^^^^^^^^^^^^^
+
+A property is defined with a name and a type. Even is python itself is
+dynamically typed, you can't change the type of a property once it is defined. A
+property can be created using :func:`GObject.property`.
+
+.. code-block:: python
+
+ from gi.repository import GObject
+
+ class MyObject(GObject.GObject):
+
+ foo = GObject.property(type=str, default='bar')
+ property_float = GObject.property(type=float)
+ def __init__(self):
+ GObject.GObject.__init__(self)
+
+Properties can also be readonly, if you want some properties to be readable but
+not writable. To do so, you can add some flags to the property definition, to control read/write access.
+Flags are :const:`GObject.PARAM_READABLE` (only read access for external code),
+:const:`GObject.PARAM_WRITABLE` (only write access),
+:const:`GObject.PARAM_READWRITE` (public):
+
+.. there is also construct things, but they
+.. doesn't seem to be functional in python
+
+.. code-block:: python
+
+ foo = GObject.property(type=str, flags = GObject.PARAM_READABLE) # won't be writable
+ bar = GObject.property(type=str, flags = GObject.PARAM_WRITABLE) # won't be readable
+
+
+You can also define new read-only properties with a new method decorated with
+:func:`GObject.property`:
+
+.. code-block:: python
+
+ from gi.repository import GObject
+
+ class MyObject(GObject.GObject):
+
+ def __init__(self):
+ GObject.GObject.__init__(self)
+
+ @GObject.property
+ def readonly(self):
+ return 'This is readonly.'
+
+You can get this property using:
+
+.. code-block:: python
+
+ my_object = MyObject()
+ print my_object.readonly
+ print my_object.get_property("readonly")
+
+There is also a way to define minimum and maximum values for numbers, using a more verbose form:
+
+.. code-block:: python
+
+ from gi.repository import GObject
+
+ class MyObject(GObject.GObject):
+
+ __gproperties__ = {
+ "int-prop": (int, # type
+ "integer prop", # nick
+ "A porperty that contains an integer", # blurb
+ 1, # min
+ 5, # max
+ 2, # default
+ GObject.PARAM_READWRITE # flags
+ ),
+ }
+
+ def __init__(self):
+ GObject.GObject.__init__(self)
+ self.int_prop = 2
+
+ def do_get_property(self, prop):
+ if prop.name == 'int-prop':
+ return self.int_prop
+ else:
+ raise AttributeError, 'unknown property %s' % prop.name
+
+ def do_set_property(self, prop, value):
+ if prop.name == 'int-prop':
+ self.int_prop = value
+ else:
+ raise AttributeError, 'unknown property %s' % prop.name
+
+
+Properties must be defined in :attr:`GObject.GObject.__gproperties__`, a
+dictionary, and handled in do_get_property and do_set_property.
+
+Watch properties
+^^^^^^^^^^^^^^^^
+
+When a property is modified, a signal is emitted, whose name is
+"notify::property_name":
+
+.. code-block:: python
+
+ my_object = MyObject()
+
+ def on_notify_foo(obj, gparamstring):
+ print "foo changed"
+
+ my_object.connect("notify::foo", on_notify_foo)
+
+ my_object.set_property("foo", "bar") # on_notify_foo will be called
+
+API
+---
+
+.. class:: GObject.GObject
+
+ .. method:: get_property(property_name)
+
+ Retrieves a property value.
+
+ .. method:: set_property(property_name, value)
+
+ Set property *property_name* to *value*.
+
+ .. method:: emit(signal_name, ...)
+
+ Emit signal *signal_name*. Signal arguments must follow, e.g. if your
+ signal is of type ``(int,)``, it must be emitted with::
+
+ self.emit(signal_name, 42)
+
+ .. method:: freeze_notify()
+
+ This method freezes all the "notify::" signals (which are
+ emitted when any property is changed) until the :meth:`thaw_notify` method is
+ called.
+
+ .. method:: thaw_notify()
+
+ Thaw all the "notify::" signals which were thawed by :meth:`freeze_notify`.
+
+ .. attribute:: __gsignals__
+
+ A dictionary where inherited class can define new signals.
+
+ Each element in the dictionary is a new signal. The key is the signal
+ name. The value is a tuple, with the form::
+
+ (GObject.SIGNAL_RUN_FIRST, None, (int,))
+
+ :const:`GObject.SIGNAL_RUN_FIRST` can be replaced with
+ :const:`GObject.SIGNAL_RUN_LAST` or :const:`GObject.SIGNAL_RUN_CLEANUP`.
+ ``None`` is the return type of the signal. ``(int,)`` is the list of the
+ parameters of the signal, it must end with a comma.
+
+ .. attribute:: __gproperties__
+
+ .. based on http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm
+
+ The :attr:`__gproperties__` dictionary is a class property where you define the
+ properties of your object. This is not the recommend way to define new
+ properties, the method written above is much less verbose. The benefits
+ of this method is that a property can be defined with more settings,
+ like the minimum or the maximum for numbers.
+
+ The key is the name of the property
+
+ The value is a tuple which describe the property.
+ The number of elements of this tuple depends on its first element but
+ the tuple will always contain at least the following items:
+
+ The first element is the property's type (e.g. ``int``, ``float``...).
+
+ The second element is the property's nick name, which is a string
+ with a short description of the property. This is generally used by
+ programs with strong introspection capabilities, like the graphical
+ user interface builder `Glade`_.
+
+ The third one is the property's description or blurb, which is
+ another string with a longer description of the property. Also used
+ by `Glade`_ and similar programs.
+
+ The last one (which is not necessarily the forth one as we will see
+ later) is the property's flags: :const:`GObject.PARAM_READABLE`,
+ :const:`GObject.PARAM_WRITABLE`, :const:`GObject.PARAM_READWRITE`.
+
+ The absolute length of the tuple depends on the property type (the
+ first element of the tuple). Thus we have the following situations:
+
+ If the type is ``bool`` or ``str``, the forth element is the
+ default value of the property.
+
+ If the type is ``int`` or ``float``, the forth element is the minimum
+ accepted value, the fifth element is the maximum accepted value
+ and the sixth element is the default value.
+
+ If the type is not one of these, there is no extra element.
+
+
+.. attribute:: GObject.SIGNAL_RUN_FIRST
+
+ Invoke the object method handler in the first emission stage.
+
+.. attribute:: GObject.SIGNAL_RUN_LAST
+
+ Invoke the object method handler in the third emission stage.
+
+.. attribute:: GObject.SIGNAL_RUN_CLEANUP
+
+ Invoke the object method handler in the last emission stage.
+
+.. attribute:: GObject.PARAM_READABLE
+
+ The property is readable.
+
+.. attribute:: GObject.PARAM_WRITABLE
+
+ The property is writable.
+
+.. attribute:: GObject.PARAM_READWRITE
+
+ The property is readable and writable.
+
+.. _Glade: http://glade.gnome.org/
Please sign in to comment.
Something went wrong with that request. Please try again.