SpinButton

A SpinButton allows the user to select a value from a range of numeric values. It has an Entry widget with increment and decrement buttons at the side. Clicking the buttons causes the value to 'spin' up and down across the range of possible values. The Entry widget may also be used to enter a value directly.

El valor puede tener un número ajustable de decimales, y el tamaño del paso es configurable. Los SpinButton también tienen una característica de «auto-repetición»: mantener pulsada una de las flechas puede, opcionalmente, causar que el valor cambie más rápidamente cuanto más tiempo se mantenga pulsada la flecha.

SpinButtons use an Adjustment object to hold information about the range of values. These Adjustment attributes are used by the Spin Button like so:

  • value: value for the Spin Button
  • lower: lower range value
  • upper: upper range value
  • step_increment: value to increment/decrement when pressing mouse button 1
  • page_increment: value to increment/decrement when pressing mouse button 2
  • page_size: unused

Además, el botón 3 del ratón se puede usar para saltar directamente a los valores upper o lower.

El SpinButton puede crear un Adjustment predeterminado, al que puede acceder mediante el método get_adjustment(), o puede especificar un Adjustment existente en el constructor.

8.3.1. Métodos

La cantidad de lugares decimales se puede alterar usando el método set_digits().

Puede establecer el valor del «spinbutton» usando el método set_value(), y obtenerlo con get_value().

El método spin() «gira» el SpinButton, como si se hubiera presionado una de sus flechas. Debe especificar un Gtk::SpinType para especificar la dirección de su posición nueva.

Para que el usuario no pueda introducir caracteres no numéricos al cuadro de entrada, pásele true al método set_numeric().

Para que el SpinButton «salte» entre sus límites superior e inferior, use el método set_wrap().

Para forzarlo a encajar en el step_increment más cercano, use set_snap_to_ticks().

Referencia

8.3.2. Ejemplo

Aquí hay un ejemplo de un SpinButton en acción:

Figura 8-6SpinButton

Código fuente

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  void on_checkbutton_snap();
  void on_checkbutton_numeric();
  void on_spinbutton_digits_changed();
  void on_button_close();

  enum enumValueFormats
  {
    VALUE_FORMAT_INT,
    VALUE_FORMAT_FLOAT
  };
  void on_button_getvalue(enumValueFormats display);

  //Child widgets:
  Gtk::Frame m_Frame_NotAccelerated, m_Frame_Accelerated;
  Gtk::Box m_HBox_NotAccelerated, m_HBox_Accelerated,
    m_HBox_Buttons;
  Gtk::Box m_VBox_Main, m_VBox, m_VBox_Day, m_VBox_Month, m_VBox_Year,
    m_VBox_Accelerated, m_VBox_Value, m_VBox_Digits;
  Gtk::Label m_Label_Day, m_Label_Month, m_Label_Year,
    m_Label_Value, m_Label_Digits,
    m_Label_ShowValue;
  Glib::RefPtr<Gtk::Adjustment> m_adjustment_day, m_adjustment_month, m_adjustment_year,
    m_adjustment_value, m_adjustment_digits;
  Gtk::SpinButton m_SpinButton_Day, m_SpinButton_Month, m_SpinButton_Year,
    m_SpinButton_Value, m_SpinButton_Digits;
  Gtk::CheckButton m_CheckButton_Snap, m_CheckButton_Numeric;
  Gtk::Button m_Button_Int, m_Button_Float, m_Button_Close;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: main.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <iostream>
#include <cstdio>

ExampleWindow::ExampleWindow()
:
  m_Frame_NotAccelerated("Not accelerated"),
  m_Frame_Accelerated("Accelerated"),
  m_VBox_Main(Gtk::Orientation::VERTICAL, 5),
  m_VBox(Gtk::Orientation::VERTICAL),
  m_VBox_Day(Gtk::Orientation::VERTICAL),
  m_VBox_Month(Gtk::Orientation::VERTICAL),
  m_VBox_Year(Gtk::Orientation::VERTICAL),
  m_VBox_Accelerated(Gtk::Orientation::VERTICAL),
  m_VBox_Value(Gtk::Orientation::VERTICAL),
  m_VBox_Digits(Gtk::Orientation::VERTICAL),
  m_Label_Day("Day: ", Gtk::Align::START),
  m_Label_Month("Month: ", Gtk::Align::START),
  m_Label_Year("Year: ", Gtk::Align::START),
  m_Label_Value("Value: ", Gtk::Align::START),
  m_Label_Digits("Digits: ", Gtk::Align::START),
  m_adjustment_day( Gtk::Adjustment::create(1.0, 1.0, 31.0, 1.0, 5.0, 0.0) ),
  m_adjustment_month( Gtk::Adjustment::create(1.0, 1.0, 12.0, 1.0, 5.0, 0.0) ),
  m_adjustment_year( Gtk::Adjustment::create(2012.0, 1.0, 2200.0, 1.0, 100.0, 0.0) ),
  m_adjustment_value( Gtk::Adjustment::create(0.0, -10000.0, 10000.0, 0.5, 100.0, 0.0) ),
  m_adjustment_digits( Gtk::Adjustment::create(2.0, 1.0, 5.0, 1.0, 1.0, 0.0) ),
  m_SpinButton_Day(m_adjustment_day),
  m_SpinButton_Month(m_adjustment_month),
  m_SpinButton_Year(m_adjustment_year),
  m_SpinButton_Value(m_adjustment_value, 1.0, 2),
  m_SpinButton_Digits(m_adjustment_digits),
  m_CheckButton_Snap("Snap to 0.5-ticks"),
  m_CheckButton_Numeric("Numeric only input mode"),
  m_Button_Int("Value as Int"),
  m_Button_Float("Value as Float"),
  m_Button_Close("Close")
{
  set_title("SpinButton");

  m_VBox_Main.set_margin(10);
  set_child(m_VBox_Main);

  m_VBox_Main.append(m_Frame_NotAccelerated);

  m_VBox.set_margin(5);
  m_Frame_NotAccelerated.set_child(m_VBox);

  /* Day, month, year spinners */

  m_VBox.set_spacing(5);
  m_VBox.append(m_HBox_NotAccelerated);

  m_Label_Day.set_expand();
  m_VBox_Day.append(m_Label_Day);

  m_SpinButton_Day.set_wrap();
  m_SpinButton_Day.set_expand();
  m_VBox_Day.append(m_SpinButton_Day);

  m_HBox_NotAccelerated.set_spacing(5);
  m_HBox_NotAccelerated.append(m_VBox_Day);

  m_Label_Month.set_expand();
  m_VBox_Month.append(m_Label_Month);

  m_SpinButton_Month.set_wrap();
  m_SpinButton_Month.set_expand();
  m_VBox_Month.append(m_SpinButton_Month);

  m_HBox_NotAccelerated.append(m_VBox_Month);

  m_Label_Year.set_expand();
  m_VBox_Year.append(m_Label_Year);

  m_SpinButton_Year.set_wrap();
  m_SpinButton_Year.set_expand();
  m_SpinButton_Year.set_size_request(55, -1);
  m_VBox_Year.append(m_SpinButton_Year);

  m_HBox_NotAccelerated.append(m_VBox_Year);

  //Accelerated:
  m_VBox_Main.append(m_Frame_Accelerated);

  m_VBox_Accelerated.set_margin(5);
  m_Frame_Accelerated.set_child(m_VBox_Accelerated);

  m_VBox_Accelerated.set_spacing(5);
  m_VBox_Accelerated.append(m_HBox_Accelerated);

  m_HBox_Accelerated.append(m_VBox_Value);

  m_Label_Value.set_expand();
  m_VBox_Value.append(m_Label_Value);

  m_SpinButton_Value.set_wrap();
  m_SpinButton_Value.set_expand();
  m_SpinButton_Value.set_size_request(100, -1);
  m_VBox_Value.append(m_SpinButton_Value);

  m_HBox_Accelerated.append(m_VBox_Digits);

  m_VBox_Digits.append(m_Label_Digits);
  m_Label_Digits.set_expand();

  m_SpinButton_Digits.set_wrap();
  m_adjustment_digits->signal_value_changed().connect( sigc::mem_fun(*this,
              &ExampleWindow::on_spinbutton_digits_changed) );

  m_VBox_Digits.append(m_SpinButton_Digits);
  m_SpinButton_Digits.set_expand();

  //CheckButtons:
  m_VBox_Accelerated.append(m_CheckButton_Snap);
  m_CheckButton_Snap.set_expand();
  m_CheckButton_Snap.set_active();
  m_CheckButton_Snap.signal_toggled().connect( sigc::mem_fun(*this,
              &ExampleWindow::on_checkbutton_snap) );

  m_VBox_Accelerated.append(m_CheckButton_Numeric);
  m_CheckButton_Numeric.set_expand();
  m_CheckButton_Numeric.set_active();
  m_CheckButton_Numeric.signal_toggled().connect( sigc::mem_fun(*this,
              &ExampleWindow::on_checkbutton_numeric) );

  //Buttons:
  m_VBox_Accelerated.append(m_HBox_Buttons);

  m_Button_Int.signal_clicked().connect( sigc::bind( sigc::mem_fun(*this,
                  &ExampleWindow::on_button_getvalue), VALUE_FORMAT_INT) );
  m_HBox_Buttons.set_spacing(5);
  m_HBox_Buttons.append(m_Button_Int);
  m_Button_Int.set_expand();

  m_Button_Float.signal_clicked().connect( sigc::bind( sigc::mem_fun(*this,
                  &ExampleWindow::on_button_getvalue), VALUE_FORMAT_FLOAT) );
  m_HBox_Buttons.append(m_Button_Float);
  m_Button_Float.set_expand();

  m_VBox_Accelerated.append(m_Label_ShowValue);
  m_Label_ShowValue.set_expand();
  m_Label_ShowValue.set_text("0");

  //Close button:
  m_Button_Close.signal_clicked().connect( sigc::mem_fun(*this,
              &ExampleWindow::on_button_close) );
  m_VBox_Main.append(m_Button_Close);
}

ExampleWindow::~ExampleWindow()
{
}


void ExampleWindow::on_button_close()
{
  hide();
}

void ExampleWindow::on_checkbutton_snap()
{
  m_SpinButton_Value.set_snap_to_ticks( m_CheckButton_Snap.get_active() );
}

void ExampleWindow::on_checkbutton_numeric()
{
  m_SpinButton_Value.set_numeric( m_CheckButton_Numeric.get_active() );
}

void ExampleWindow::on_spinbutton_digits_changed()
{
  m_SpinButton_Value.set_digits( m_SpinButton_Digits.get_value_as_int() );
}

void ExampleWindow::on_button_getvalue(enumValueFormats display)
{
  gchar buf[32];

  if (display == VALUE_FORMAT_INT)
    sprintf (buf, "%d", m_SpinButton_Value.get_value_as_int());
  else
    sprintf (buf, "%0.*f", m_SpinButton_Value.get_digits(),
            m_SpinButton_Value.get_value());

  m_Label_ShowValue.set_text(buf);
}