21.2. Recuperar la Selección

Recuperar la selección es un proceso asíncrono. Para iniciar el proceso es necesario llamar a:

  result = widget.selection_convert(selection, target, time=0)
    

Que convierte la selección selection en el formato especificado por el objetivo target. La selección selection es un átomo correspondiente al tipo de selección. Las selecciones comunes son las cadenas de texto:

  PRIMARY    # primaria

  SECONDARY  # secundaria
    

Si es posible, el campo tiempo time debería ser el momento en el que se produjo el evento que ocasionó la selección. Esto ayuda a cerciorarse que los eventos ocurren en el orden en el que el usuario los solicita. Sin embargo, si no está disponible (por ejemplo, si la conversión se produjo en una señal "clicked"), entonces se puede utilizar 0, que significa el momento actual. El resultado será TRUE (verdadero) si la conversión tuvo éxito, o FALSE (falso) en caso contrario.

Cuando el dueño de la selección responde a la petición, una señal "selection_received" (selección_recibida) se envia a la aplicación. El manejador de esta señal recibe un objeto de tipo gtk.SelectionData, que tiene los siguientes atributos:

  selection # selección
  target    # objetivo
  type      # tipo
  format    # formato
  data      # datos
    

selection y target son los valores que se dieron en el método selection_convert() .

type es un átomo que identifica el tipo de datos que ha devuelto el dueño de la selección. Algunos valores posibles son "STRING", una cadena de caracteres latin-1, "ATOM", una serie de átomos, "INTEGER", un entero, "image/x-xpixmap", etc. La mayoría de los objetivos sólo pueden devolver un tipo.

La lista de átomos estándar en X y GTK+ es:

  PRIMARY
  SECONDARY
  ARC
  ATOM
  BITMAP
  CARDINAL
  COLORMAP
  CURSOR
  CUT_BUFFER0
  CUT_BUFFER1
  CUT_BUFFER2
  CUT_BUFFER3
  CUT_BUFFER4
  CUT_BUFFER5
  CUT_BUFFER6
  CUT_BUFFER7
  DRAWABLE
  FONT
  INTEGER
  PIXMAP
  POINT
  RECTANGLE
  RESOURCE_MANAGER
  RGB_COLOR_MAP
  RGB_BEST_MAP
  RGB_BLUE_MAP
  RGB_DEFAULT_MAP
  RGB_GRAY_MAP
  RGB_GREEN_MAP
  RGB_RED_MAP
  STRING
  VISUALID
  WINDOW
  WM_COMMAND
  WM_HINTS
  WM_CLIENT_MACHINE
  WM_ICON_NAME
  WM_ICON_SIZE
  WM_NAME
  WM_NORMAL_HINTS
  WM_SIZE_HINTS
  WM_ZOOM_HINTS
  MIN_SPACE
  NORM_SPACE
  MAX_SPACE  END_SPACE,
  SUPERSCRIPT_X
  SUPERSCRIPT_Y
  SUBSCRIPT_X
  SUBSCRIPT_Y
  UNDERLINE_POSITION
  UNDERLINE_THICKNESS
  STRIKEOUT_ASCENT
  STRIKEOUT_DESCENT
  ITALIC_ANGLE
  X_HEIGHT
  QUAD_WIDTH
  WEIGHT
  POINT_SIZE
  RESOLUTION
  COPYRIGHT
  NOTICE
  FONT_NAME
  FAMILY_NAME
  FULL_NAME
  CAP_HEIGHT
  WM_CLASS
  WM_TRANSIENT_FOR
  CLIPBOARD

format da la longitud de las unidades (por ejemplo caracteres) en bits. Normalmente se puede obviar este parámetro al recibir datos.

data contiene los datos devueltos en forma de cadena de texto.

PyGTK empaqueta todos los datos recibidos en una cadena de texto. Esto hace que sea fácil manipular objetivos de cadenas de texto. Para obtener objetivos de otros tipos (como ATOM o INTEGER) el programa debe extraer la información de la cadena de texto devuelta. PyGTK proporciona dos métodos para obtener texto y una lista de objetivos a partir de los datos de la selección:

  text = selection_data.get_text()

  targets = selection_data.get_targets()
    

donde text es una cadena de texto que contiene el texto de la selección y targets es una lista de los objetivos que acepta la selección.

Dado un gtk.SelectionData que contiene una lista de objetivos, el método:

  has_text = selection_data.targets_include_text()
    

devolverá TRUE (verdadero) si uno o más de los objetivos pueden proporcionar texto.

El programa de ejemplo getselection.py enseña cómo recibir un objetivo "STRING" o "TARGETS" desde la selección primaria para luego imprimir los datos correspondientes en la consola al hacer clic en el botón asociado. La figura Figura 21.1, “Ejemplo de Obtención de la Selección” muestra la ventana del programa:

Figura 21.1. Ejemplo de Obtención de la Selección

Ejemplo de Obtención de la Selección

El código fuente de getselection.py es:

    1    #!/usr/bin/env python
    2
    3    # ejemplo getselection.py
    4
    5    import pygtk
    6    pygtk.require('2.0')
    7    import gtk
    8
    9    class GetSelectionExample:
   10        # Gestor de la señal que se llama cuando la usuaria
   11        # pulsa el botón "Get String Target"
   12        def get_stringtarget(self, widget):
   13            # Se solicita el objetivo "STRING" para la selección primaria
   14            ret = widget.selection_convert("PRIMARY", "STRING")
   15            return
   16
   17        # Gestor de señal que se invoca cuando la usuaria pulsa el botón "Get Targets"
   18        def get_targets(self, widget):
   19            # Se solicita el objetivo "TARGETS" para la selección primaria
   20            ret = widget.selection_convert("PRIMARY", "TARGETS")
   21            return
   22
   23        # Gestor de señal llamado cuando el propietario de la selección devuelve los datos
   24        def selection_received(self, widget, selection_data, data):
   25            # Nos aseguramos de que los datos se reciben en el formato esperado
   26            if str(selection_data.type) == "STRING":
   27                # Mostramos la cadena recibida
   28                print "STRING TARGET: %s" % selection_data.get_text()
   29
   30            elif str(selection_data.type) == "ATOM":
   31                # Mostramos la lista de objetivos recibida
   32                targets = selection_data.get_targets()
   33                for target in targets:
   34                    name = str(target)
   35                    if name != None:
   36                        print "%s" % name
   37                    else:
   38                        print "(bad target)"
   39            else:
   40                print "Selection was not returned as \"STRING\" or \"ATOM\"!"
   41
   42            return gtk.FALSE
   43
   44
   45        def __init__(self):
   46            # Creamos la ventana principal
   47            window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   48            window.set_title("Get Selection")
   49            window.set_border_width(10)
   50            window.connect("destroy", lambda w: gtk.main_quit())
   51
   52            vbox = gtk.VBox(gtk.FALSE, 0)
   53            window.add(vbox)
   54            vbox.show()
   55
   56            # Creamos un botón que al pulsarlo se obtiene la cadena de objetivo
   57            button = gtk.Button("Get String Target")
   58            eventbox = gtk.EventBox()
   59            eventbox.add(button)
   60            button.connect_object("clicked", self.get_stringtarget, eventbox)
   61            eventbox.connect("selection_received", self.selection_received)
   62            vbox.pack_start(eventbox)
   63            eventbox.show()
   64            button.show()
   65
   66            # Creamos un botón que devuelve los objetivos al pulsarlo
   67            button = gtk.Button("Get Targets")
   68            eventbox = gtk.EventBox()
   69            eventbox.add(button)
   70            button.connect_object("clicked", self.get_targets, eventbox)
   71            eventbox.connect("selection_received", self.selection_received)
   72            vbox.pack_start(eventbox)
   73            eventbox.show()
   74            button.show()
   75
   76            window.show()
   77
   78    def main():
   79        gtk.main()
   80        return 0
   81
   82    if __name__ == "__main__":
   83        GetSelectionExample()
   84        main()

    

Las lineas 30-38 se encargan de la obtención de los datos de selección de "TARGETS" (objetivos) e imprime la lista de los nombres de los objetivos. Los botones están insertados en sus propias cajas de eventos puesto que una selección debe estar asociada a una gtk.gdk.Window y los botones son controles sin ventana propia en GTK+2.0.