スピンボタン

SpinButtonを使ってユーザーは数値の範囲から一つ値を選択することができます。これはエントリウィジットひとつとその横に上下の矢印ボタンを備えています。このボタンをクリックすることにより、ウィジットの値を可能な範囲で上下に"スピン"させます。このEntryウィジットには直接、値を入力することも可能です。

値は調整可能な10進配置の数であり、変化のステップサイズも調節可能です。SpinButtonにも"自動リピート"機能がついています。つまり、矢印ボタンを押しつづければ押しつづけるほど、値の変化をどんどん速くさせるようにできます。

SpinButtonアジャストメントオブジェクトを使って値の範囲についての情報を保持します。以下のアジャストメントの属性がスピンボタンに使われます:

これらに加えて、マウスの中クリックを上限値か下限値に直接ジャンプするのに使うことができます。

SpinButtonはデフォルトのAdjustmentを生成することができます。get_adjustment()メソッドを介してアクセスしてください。あるいは、既存のAdjustmentをコンストラクタで指定することもできます。

メソッド

数値の10進配置はset_digits()を使って変更することができます。

スピンボタンの値はset_value()メソッドを使って設定できます。取得するにはget_value()を使ってください。

spin()メソッドはSpinButtonを"スピン"させます。ちょうど矢印ボタンのひとつがクリックされたのと同じです。これにはGtk::SpinTypeオブジェクトを渡して、スピンの方向か新しい数値を指定する必要があります。

ユーザーが数値でない文字をエントリボックスに入力するのを防ぐには、set_numeric()メソッドにtrueを渡してください。

SpinButtonが数値を上限と下限でラップする(循環する)ようにするには、set_wrap()メソッドを使ってください。

値の変化がstep_incrementに最も近い値にスナップするよう強制するには、set_snap_to_ticks()メソッドを使ってください。

スピンボタンのアップデートポリシーはset_update_policy()メソッドで変更できます。Gtk::UPDATE_ALWAYSGtk::UPDATE_IF_VALIDのどちらかを指定してください。Gtk::UPDATE_ALWAYSを使うと、SpinButtonはエントリボックスのテキストを数値に変換する際に生じたエラーを無視するようになります。ですから、この設定はSpinButtonに数値でない値を許容させることになります。変更を即座に反映するよう強制するには、update()メソッドを使ってください。

Reference

以下のものがSpinButtonの実際に動作するコード例です

Figure 6.3. SpinButton

SpinButton

Source Code

File: examplewindow.h

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

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

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

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

  //Child widgets:
  Gtk::Frame m_Frame_NotAccelerated, m_Frame_Accelerated;
  Gtk::HBox m_HBox_NotAccelerated, m_HBox_Accelerated,
    m_HBox_Buttons;
  Gtk::VBox 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;
  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

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

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  //Shows the window and returns when it is closed.
  Gtk::Main::run(window);

  return 0;
}

File: examplewindow.cc

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

ExampleWindow::ExampleWindow()
:
  m_Frame_NotAccelerated("Not accelerated"),
  m_Frame_Accelerated("Accelerated"),
  m_VBox_Main(false, 5),
  m_Label_Day("Day: "),
  m_Label_Month("Month: "),
  m_Label_Year("Year: "),
  m_Label_Value("Value: "),
  m_Label_Digits("Digits: "),
  m_adjustment_day(1.0, 1.0, 31.0, 1.0, 5.0, 0.0),
  m_adjustment_month(1.0, 1.0, 12.0, 1.0, 5.0, 0.0),
  m_adjustment_year(1998.0, 0.0, 2100.0, 1.0, 100.0, 0.0),
  m_adjustment_value(0.0, -10000.0, 10000.0, 0.5, 100.0, 0.0),
  m_adjustment_digits(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_border_width(10);
  add(m_VBox_Main);

  m_VBox_Main.pack_start(m_Frame_NotAccelerated);

  m_VBox.set_border_width(5);
  m_Frame_NotAccelerated.add(m_VBox);

  /* Day, month, year spinners */

  m_VBox.pack_start(m_HBox_NotAccelerated, Gtk::PACK_EXPAND_WIDGET, 5);

  m_Label_Day.set_alignment(Gtk::ALIGN_LEFT);
  m_VBox_Day.pack_start(m_Label_Day);

  m_SpinButton_Day.set_wrap();

  m_VBox_Day.pack_start(m_SpinButton_Day);

  m_HBox_NotAccelerated.pack_start(m_VBox_Day, Gtk::PACK_EXPAND_WIDGET, 5);

  m_Label_Month.set_alignment(Gtk::ALIGN_LEFT);
  m_VBox_Month.pack_start(m_Label_Month);

  m_SpinButton_Month.set_wrap();
  m_VBox_Month.pack_start(m_SpinButton_Month);

  m_HBox_NotAccelerated.pack_start(m_VBox_Month, Gtk::PACK_EXPAND_WIDGET, 5);

  m_Label_Year.set_alignment(Gtk::ALIGN_LEFT);
  m_VBox_Year.pack_start(m_Label_Year);

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

  m_HBox_NotAccelerated.pack_start(m_VBox_Year, Gtk::PACK_EXPAND_WIDGET, 5);

  //Accelerated:
  m_VBox_Main.pack_start(m_Frame_Accelerated);

  m_VBox_Accelerated.set_border_width(5);
  m_Frame_Accelerated.add(m_VBox_Accelerated);

  m_VBox_Accelerated.pack_start(m_HBox_Accelerated, Gtk::PACK_EXPAND_WIDGET, 5);

  m_HBox_Accelerated.pack_start(m_VBox_Value, Gtk::PACK_EXPAND_WIDGET, 5);

  m_Label_Value.set_alignment(Gtk::ALIGN_LEFT);
  m_VBox_Value.pack_start(m_Label_Value);

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

  m_HBox_Accelerated.pack_start(m_VBox_Digits, Gtk::PACK_EXPAND_WIDGET, 5);

  m_Label_Digits.set_alignment(Gtk::ALIGN_LEFT);
  m_VBox_Digits.pack_start(m_Label_Digits);

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

  m_VBox_Digits.pack_start(m_SpinButton_Digits);


  //CheckButtons:
  m_VBox_Accelerated.pack_start(m_CheckButton_Snap);
  m_CheckButton_Snap.set_active();
  m_CheckButton_Snap.signal_clicked().connect( sigc::mem_fun(*this,
              &ExampleWindow::on_checkbutton_snap) );

  m_VBox_Accelerated.pack_start(m_CheckButton_Numeric);
  m_CheckButton_Numeric.set_active();
  m_CheckButton_Numeric.signal_clicked().connect( sigc::mem_fun(*this,
              &ExampleWindow::on_checkbutton_numeric) );


  //Buttons:
  m_VBox_Accelerated.pack_start (m_HBox_Buttons, Gtk::PACK_SHRINK, 5);

  m_Button_Int.signal_clicked().connect( sigc::bind( sigc::mem_fun(*this,
                  &ExampleWindow::on_button_getvalue), VALUE_FORMAT_INT) );
  m_HBox_Buttons.pack_start(m_Button_Int, Gtk::PACK_EXPAND_WIDGET, 5);

  m_Button_Float.signal_clicked().connect( sigc::bind( sigc::mem_fun(*this,
                  &ExampleWindow::on_button_getvalue), VALUE_FORMAT_FLOAT) );
  m_HBox_Buttons.pack_start(m_Button_Float, Gtk::PACK_EXPAND_WIDGET, 5);

  m_VBox_Accelerated.pack_start(m_Label_ShowValue);
  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.pack_start(m_Button_Close, Gtk::PACK_SHRINK);

  show_all_children();
}

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);
}