El control SpinButton (Botón Aumentar/ Disminuir) se usa generalmente para permitir al usuario seleccionar un valor dentro de un rango de valores numéricos. Consiste en una caja de entrada de texto con botones de flecha arriba y abajo a un lado. Seleccionando uno de los botones causa que el valor aumente o disminuya en el rango de valores posibles. La caja de entrada también puede editarse directamente para introducir un valor específico.
El SpinButton permite que el valor tenga cero o más cifras decimales y puede incrementarse/decrementarse en pasos configurables. La acción de mantener pulsado uno de los botones opcionalmente provoca una aceleración en el cambio del valor correspondiente al tiempo que se mantenga presionado.
El SpinButton usa un objeto Adjustment (Ajuste) para almacenar la información del rango de valores que el botón aumentar/disminuir puede tomar. Esto le hace un control muy útil.
Recuerda que un control Adjustment (Ajuste) se crea con la siguiente función, que muestra la información que almacena:
adjustment = gtk.Adjustment(value=0, lower=0, upper=0, step_incr=0, page_incr=0, page_size=0) |
Estos atributos de un Adjustment (Ajuste) se usan en el SpinButton de la siguiente manera:
| value | valor inicial para el Botón Aumentar/Disminuir |
| lower | el valor más bajo del rango |
| upper | el valor más alto del rango |
| step_increment | valor que se incrementa/decrementa cuando se pulsa el botón-1 del ratón en un botón |
| page_increment | valor que se incrementa/decrementa cuando se pulsa el botón-2 del ratón en un botón |
| page_size | no se usa |
Adicionalmente, el botón del ratón botón-3 se puede usar para saltar directamente a los valores upper (superior) y lower (inferior) cuando se usa para seleccionar uno de los botones. Veamos como crear un SpinButton (Botón Aumentar/Disminuir):
spin_button = gtk.SpinButton(adjustment=None, climb_rate=0.0, digits=0) |
El argumento climb_rate (razón de escalada) puede tomar un valor entre 0.0 y 1.0 e indica la cantidad de aceleración que el SpinButton tiene. El argumento digits especifica el número de cifras decimales que se mostrarán.
Un SpinButton se puede reconfigurar después de su creación usando el siguiente método:
spin_button.configure(adjustment, climb_rate, digits) |
La variable spin_button especifica el botón aumentar/disminuir que se va a reconfigurar. Los otros argumentos son los mismos que antes.
El adjustment (ajuste) se puede fijar y recupar independientemente usando los siguientes dos métodos:
spin_button.set_adjustment(adjustment)
adjustment = spin_button.get_adjustment()
|
El número de cifras decimales también se puede cambiar usando:
spin_button.set_digits(digits)
|
El valor que un SpinButton esta mostrando actualmente se puede cambiar usando el siguiente método:
spin_button.set_value(value)
|
El valor actual de un SpinButton se puede recuperar como un valor real o como un valor entero usando los siguientes métodos:
float_value = spin_button.get_value() int_value = spin_button.get_value_as_int() |
Si quieres alterar el valor de un SpinButton relativo a su valor actual, entonces usa el siguiente método:
spin_button.spin(direction, increment) |
El parámetro direction (dirección) puede tomar uno de los siguientes valores:
SPIN_STEP_FORWARD # paso hacia adelante SPIN_STEP_BACKWARD # paso hacia atrás SPIN_PAGE_FORWARD # página hacia adelante SPIN_PAGE_BACKWARD # página hacia atrás SPIN_HOME # inicio SPIN_END # fin SPIN_USER_DEFINED # definido por el usuario |
Este método comprime bastante funcionalidad, que intentaré explicar ahora. Muchos de estos parámetros usan valores del objeto Adjustment (Ajuste) que está asociado con un SpinButton (Botón Aumentar/Disminuir).
SPIN_STEP_FORWARD (paso adelante) y SPIN_STEP_BACKWARD (paso atrás) cambian el valor del SpinButton con una cantidad especificada por el increment (incremento), a menos que increment (incremento) sea igual a 0, en cuyo caso el valor se modifica con el step_increment (incremento de paso) del Adjustment.
SPIN_PAGE_FORWARD (página adelante) y SPIN_PAGE_BACKWARD (página atrás) simplemente alteran el valor del SpinButton por increment (incremento).
SPIN_HOME (inicio) pone el valor del SpinButton a la parte de abajo del rango del Adjustment .
SPIN_END (fin) fija el valor del SpinButton a la parte de arriba del rango del Adjustment .
SPIN_USER_DEFINED (definido por el usuario) simplemente modifica el valor del SpinButton con la cantidad especificada.
Ahora nos alejamos de los métodos para fijar y recuperar los atributos del rango de un SpinButton , y nos centramos en los métodos que modifican la apariencia y comportamiento de un control SpinButton propiamente.
El primero de estos métodos se usa para limitar la caja de texto del SpinButton para que solo contenga un valor numérico. Esto evita que el usuario escriba cualquier otra cosa que no sea un valor numérico dentro de la caja de texto de un SpinButton:
spin_button.set_numeric(numeric)
|
El argumento numeric es TRUE para limitar la caja de texto a valores numéricos o FALSE para quitar esta limitación.
Puedes fijar si quieres que el valor del SpinButton se quede en los valores inferior y superior del rango con el siguiente método:
spin_button.set_wrap(wrap)
|
El SpinButton limitará los valores dentro del rango si wrap es TRUE.
Puedes hacer que el SpinButton redondee el valor al step_increment (incremento) más cercano, lo cual se fija dentro del objeto Adjustment usado en el SpinButton. Esto se consigue con el siguiente método cuando el argumento snap_to_ticks es TRUE:
spin_button.set_snap_to_ticks(snap_to_ticks)
|
La política de actualización de un SpinButton se cambia con el siguiente método:
spin_button.set_update_policy(policy)
|
Los valores posibles de esta política son:
UPDATE_ALWAYS # actualizar siempre UPDATE_IF_VALID # actualizar si es válido |
Estas políticas afectan el comportamiento de un SpinButton cuando analiza el texto insertado y sincroniza su valor con los valores del Adjustment.
En el caso de UPDATE_IF_VALID (actualizar si es válido) el valor del SpinButton sólo cambia si el texto es un valor numérico que está dentro del rango especificado por el Adjustment. En cualquier otro caso el texto se resetea al valor actual.
En el caso de UPDATE_ALWAYS (actualizar siempre) se ignoran los errores de conversión al pasar el texto a un valor numérico.
Finalmente, puedes especificar una actualización por ti mismo SpinButton :
spin_button.update() |
El programa de ejemplo spinbutton.py muestra el uso de botones de aumentar/disminuir incluyendo el uso de un número de características. La figura Figura 9.11. Ejemplo de Botón Aumentar/Disminuir muestra el resultado de ejecutar el programa de ejemplo:
El código fuente spinbutton.py es:
1 #!/usr/bin/env python
2
3 # example spinbutton.py
4
5 import gtk
6
7 class SpinButtonExample:
8 def toggle_snap(self, widget, spin):
9 spin.set_snap_to_ticks(widget.get_active())
10
11 def toggle_numeric(self, widget, spin):
12 spin.set_numeric(widget.get_active())
13
14 def change_digits(self, widget, spin, spin1):
15 spin1.set_digits(spin.get_value_as_int())
16
17 def get_value(self, widget, data, spin, spin2, label):
18 if data == 1:
19 buf = "%d" % spin.get_value_as_int()
20 else:
21 buf = "%0.*f" % (spin2.get_value_as_int(),
22 spin.get_value())
23 label.set_text(buf)
24
25 def __init__(self):
26 window = gtk.Window(gtk.WINDOW_TOPLEVEL)
27 window.connect("destroy", gtk.mainquit)
28 window.set_title("Spin Button")
29
30 main_vbox = gtk.VBox(gtk.FALSE, 5)
31 main_vbox.set_border_width(10)
32 window.add(main_vbox)
33
34 frame = gtk.Frame("Not accelerated")
35 main_vbox.pack_start(frame, gtk.TRUE, gtk.TRUE, 0)
36
37 vbox = gtk.VBox(gtk.FALSE, 0)
38 vbox.set_border_width(5)
39 frame.add(vbox)
40
41 # Day, month, year spinners
42 hbox = gtk.HBox(gtk.FALSE, 0)
43 vbox.pack_start(hbox, gtk.TRUE, gtk.TRUE, 5)
44
45 vbox2 = gtk.VBox(gtk.FALSE, 0)
46 hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, 5)
47
48 label = gtk.Label("Day :")
49 label.set_alignment(0, 0.5)
50 vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
51
52 adj = gtk.Adjustment(1.0, 1.0, 31.0, 1.0, 5.0, 0.0)
53 spinner = gtk.SpinButton(adj, 0, 0)
54 spinner.set_wrap(gtk.TRUE)
55 vbox2.pack_start(spinner, gtk.FALSE, gtk.TRUE, 0)
56
57 vbox2 = gtk.VBox(gtk.FALSE, 0)
58 hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, 5)
59
60 label = gtk.Label("Month :")
61 label.set_alignment(0, 0.5)
62 vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
63
64 adj = gtk.Adjustment(1.0, 1.0, 12.0, 1.0, 5.0, 0.0)
65 spinner = gtk.SpinButton(adj, 0, 0)
66 spinner.set_wrap(gtk.TRUE)
67 vbox2.pack_start(spinner, gtk.FALSE, gtk.TRUE, 0)
68
69 vbox2 = gtk.VBox(gtk.FALSE, 0)
70 hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, 5)
71
72 label = gtk.Label("Year :")
73 label.set_alignment(0, 0.5)
74 vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
75
76 adj = gtk.Adjustment(1998.0, 0.0, 2100.0, 1.0, 100.0, 0.0)
77 spinner = gtk.SpinButton(adj, 0, 0)
78 spinner.set_wrap(gtk.FALSE)
79 spinner.set_size_request(55, -1)
80 vbox2.pack_start(spinner, gtk.FALSE, gtk.TRUE, 0)
81
82 frame = gtk.Frame("Accelerated")
83 main_vbox.pack_start(frame, gtk.TRUE, gtk.TRUE, 0)
84
85 vbox = gtk.VBox(gtk.FALSE, 0)
86 vbox.set_border_width(5)
87 frame.add(vbox)
88
89 hbox = gtk.HBox(gtk.FALSE, 0)
90 vbox.pack_start(hbox, gtk.FALSE, gtk.TRUE, 5)
91
92 vbox2 = gtk.VBox(gtk.FALSE, 0)
93 hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, 5)
94
95 label = gtk.Label("Value :")
96 label.set_alignment(0, 0.5)
97 vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
98
99 adj = gtk.Adjustment(0.0, -10000.0, 10000.0, 0.5, 100.0, 0.0)
100 spinner1 = gtk.SpinButton(adj, 1.0, 2)
101 spinner1.set_wrap(gtk.TRUE)
102 spinner1.set_size_request(100, -1)
103 vbox2.pack_start(spinner1, gtk.FALSE, gtk.TRUE, 0)
104
105 vbox2 = gtk.VBox(gtk.FALSE, 0)
106 hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, 5)
107
108 label = gtk.Label("Digits :")
109 label.set_alignment(0, 0.5)
110 vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
111
112 adj = gtk.Adjustment(2, 1, 5, 1, 1, 0)
113 spinner2 = gtk.SpinButton(adj, 0.0, 0)
114 spinner2.set_wrap(gtk.TRUE)
115 adj.connect("value_changed", self.change_digits, spinner2, spinner1)
116 vbox2.pack_start(spinner2, gtk.FALSE, gtk.TRUE, 0)
117
118 hbox = gtk.HBox(gtk.FALSE, 0)
119 vbox.pack_start(hbox, gtk.FALSE, gtk.TRUE, 5)
120
121 button = gtk.CheckButton("Snap to 0.5-ticks")
122 button.connect("clicked", self.toggle_snap, spinner1)
123 vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
124 button.set_active(gtk.TRUE)
125
126 button = gtk.CheckButton("Numeric only input mode")
127 button.connect("clicked", self.toggle_numeric, spinner1)
128 vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
129 button.set_active(gtk.TRUE)
130
131 val_label = gtk.Label("")
132
133 hbox = gtk.HBox(gtk.FALSE, 0)
134 vbox.pack_start(hbox, gtk.FALSE, gtk.TRUE, 5)
135 button = gtk.Button("Value as Int")
136 button.connect("clicked", self.get_value, 1, spinner1, spinner2,
137 val_label)
138 hbox.pack_start(button, gtk.TRUE, gtk.TRUE, 5)
139
140 button = gtk.Button("Value as Float")
141 button.connect("clicked", self.get_value, 2, spinner1, spinner2,
142 val_label)
143 hbox.pack_start(button, gtk.TRUE, gtk.TRUE, 5)
144
145 vbox.pack_start(val_label, gtk.TRUE, gtk.TRUE, 0)
146 val_label.set_text("0")
147
148 hbox = gtk.HBox(gtk.FALSE, 0)
149 main_vbox.pack_start(hbox, gtk.FALSE, gtk.TRUE, 0)
150
151 button = gtk.Button("Close")
152 button.connect("clicked", gtk.mainquit)
153 hbox.pack_start(button, gtk.TRUE, gtk.TRUE, 5)
154 window.show_all()
155
156 def main():
157 gtk.main()
158 return 0
159
160 if __name__ == "__main__":
161 SpinButtonExample()
162 main()
|