GTK+ 2.0 Tutorial

<<< Previous

Miscellaneous Widgets

Next >>>


Кнопки "карусели"(Spin Buttons)

Кнопки "карусели" используются для пошагового изменения определенного значения в любом направлении, это похоже на прокручивание. Этот виджет выглядит как две кнопки со стрелками расположенные друг над другом, обычно он располагается сбоку в виджете ввода текста. Нажатие на одну из этих кнопок приводит к прокручиванию значений в ту или в другую сторону. При этом строка ввода может уже содержать определенное значение.

Кнопка "карусель" может иметь изначально нулевое или десятичное значение и выполнять пошаговое увеличение или уменьшение. Удержание одной из кнопок в нажатом состоянии приводит к ускоренному изменению значения, в зависимости от времени удержания.

Кнопки "карусели" используют Adjustment объекты для содержания информации о возможных значениях регулирования. Это делает данный виджет более мощным в использовании.

Вспомните что adjustment widget создаются с помощью функции которая содержит следующую информацию:

GtkObject *gtk_adjustment_new( gdouble value, gdouble lower, gdouble upper, gdouble step_increment, gdouble page_increment, gdouble page_size );

Эти атрибуты регулирования используются кнопками "карусель" следующим образом:

Дополнительно можно использовать кнопку-3 мыши для перехода сразу к высшему или низшему значению регулировок, в зависимости от выбранной кнопки. Создание новой кнопки "карусель":

GtkWidget *gtk_spin_button_new( GtkAdjustment *adjustment, gdouble climb_rate, guint digits );

Аргумент climb_rate должен иметь значение между 0.0 и 1.0 и показывает степень ускорения прокручивания. Аргумент digits определяет кол-во цифр после запятой в десятичных значениях.

Кнопку "карусель" можно переконфигурировать после создания с помощью следующей функции:

void gtk_spin_button_configure( GtkSpinButton *spin_button, GtkAdjustment *adjustment, gdouble climb_rate, guint digits );

Аргумент spin_button определяет что кнопка "карусель" должна быть переконфигурирована. Другие аргументы несут новые значения.

Регулировки могут быть установлены с помощью двух функций:

void gtk_spin_button_set_adjustment( GtkSpinButton *spin_button, GtkAdjustment *adjustment ); GtkAdjustment *gtk_spin_button_get_adjustment( GtkSpinButton *spin_button );

Кол-во цифр после запятой в десятичных значениях тоже может быть изменено:

void gtk_spin_button_set_digits( GtkSpinButton *spin_button, guint digits) ;

Текущее значение можно изменять с помощью:

void gtk_spin_button_set_value( GtkSpinButton *spin_button, gdouble value );

Определить текущее значение, десятичное или целое,  можно при помощи следующих двух функций:

gdouble gtk_spin_button_get_value ( GtkSpinButton *spin_button ); gint gtk_spin_button_get_value_as_int( GtkSpinButton *spin_button );

Если вы хотите изменить значение кнопки по отношению к текущему значению, то используйте следующую функцию:

void gtk_spin_button_spin( GtkSpinButton *spin_button, GtkSpinType direction, gdouble increment );

Параметр direction может принимать одно из этих значений:

GTK_SPIN_STEP_FORWARD GTK_SPIN_STEP_BACKWARD GTK_SPIN_PAGE_FORWARD GTK_SPIN_PAGE_BACKWARD GTK_SPIN_HOME GTK_SPIN_END GTK_SPIN_USER_DEFINED

Эта функция упаковывается в значительное количество выполняемых функций, которые я попытаюсь объяснить. Многие настройки используемые объектом регулировки (Adjustment object) связаны с кнопкой "карусель".

GTK_SPIN_STEP_FORWARD и GTK_SPIN_STEP_BACKWARD изменяет значение Кнопки "карусель" количеством, определенным приращением, если приращение не равно 0, когда значение изменено значением step_increment в Adjustment.

GTK_SPIN_PAGE_FORWARD и GTK_SPIN_PAGE_BACKWARD просто изменяет значение кнопки "карусель" приращением (increment).

GTK_SPIN_HOME устанавливает значение в основание регулятора диапазона.

GTK_SPIN_END устанавливает значение к вершине регулятора диапазона.

GTK_SPIN_USER_DEFINED  просто изменяет значение указанным количеством.

Мы закончили с рассмотрением функций отвечающих за установки и определения признаков кнопок "карусель" и переходим к функциям непосредственного создания виджета кнопка "карусель".

Первая функция ограничивает поле кнопки "карусель" так, чтобы оно могло содержать только числовое значение. Это не позволяет пользователю печатать ничего кроме цифр в данном поле:

void gtk_spin_button_set_numeric( GtkSpinButton *spin_button, gboolean numeric );

Следующая функция определяет возможность кругового изменения значения, когда по достижению верхнего или нижнего значения, изменение продолжается с противоположного конца:

void gtk_spin_button_set_wrap( GtkSpinButton *spin_button, gboolean wrap );

Вы можете установить приблизительное значение к самому близкому step_increment, который установлен в пределах объекта регулирования, используемого с Кнопкой "карусель":

void gtk_spin_button_set_snap_to_ticks( GtkSpinButton *spin_button, gboolean snap_to_ticks );

Политика обновления для кнопки "карусель" (Spin Button) может быть определена с помощью функции:

void gtk_spin_button_set_update_policy( GtkSpinButton *spin_button, GtkSpinButtonUpdatePolicy policy );

Возможные значения аргумента policy GTK_UPDATE_ALWAYS или GTK_UPDATE_IF_VALID.

Эта политика затрагивает поведение Кнопки "карусель", анализируя вставленный текст и синхронизируя его значение со значениями Настройки (Adjustment).

В случае GTK_UPDATE_IF_VALID если текстовый ввод изменен - числовое значение находится в диапазоне регулирования. Иначе текст сбрасывается к текущему значению.

В случае GTK_UPDATE_ALWAYS мы игнорируем ошибки, преобразовывая текст в числовое значение.

Наконец вы можете непосредственно обновлять кнопку "карусель":

void gtk_spin_button_update( GtkSpinButton *spin_button );

Пример:

#include <stdio.h> #include <gtk/gtk.h> static GtkWidget *spinner1; void toggle_snap( GtkWidget *widget, GtkSpinButton *spin ) { gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active); } void toggle_numeric( GtkWidget *widget, GtkSpinButton *spin ) { gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active); } void change_digits( GtkWidget *widget, GtkSpinButton *spin ) { gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1), gtk_spin_button_get_value_as_int (spin)); } void get_value( GtkWidget *widget, gpointer data ) { gchar buf[32]; GtkLabel *label; GtkSpinButton *spin; spin = GTK_SPIN_BUTTON (spinner1); label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data")); if (GPOINTER_TO_INT (data) == 1) sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin)); else sprintf (buf, "%0.*f", spin->digits, gtk_spin_button_get_value (spin)); gtk_label_set_text (label, buf); } int main( int argc, char *argv[] ) { GtkWidget *window; GtkWidget *frame; GtkWidget *hbox; GtkWidget *main_vbox; GtkWidget *vbox; GtkWidget *vbox2; GtkWidget *spinner2; GtkWidget *spinner; GtkWidget *button; GtkWidget *label; GtkWidget *val_label; GtkAdjustment *adj; /* Инициализируем GTK */ gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_window_set_title (GTK_WINDOW (window), "Spin Button"); main_vbox = gtk_vbox_new (FALSE, 5); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10); gtk_container_add (GTK_CONTAINER (window), main_vbox); frame = gtk_frame_new ("Not accelerated"); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); vbox = gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); gtk_container_add (GTK_CONTAINER (frame), vbox); /* Прокручивание - день, месяц, год */ hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5); vbox2 = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5); label = gtk_label_new ("Day :"); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0); adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 31.0, 1.0, 5.0, 0.0); spinner = gtk_spin_button_new (adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE); gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0); vbox2 = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5); label = gtk_label_new ("Month :"); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0); adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0, 5.0, 0.0); spinner = gtk_spin_button_new (adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE); gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0); vbox2 = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5); label = gtk_label_new ("Year :"); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0); adj = (GtkAdjustment *) gtk_adjustment_new (1998.0, 0.0, 2100.0, 1.0, 100.0, 0.0); spinner = gtk_spin_button_new (adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), FALSE); gtk_widget_set_size_request (spinner, 55, -1); gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0); frame = gtk_frame_new ("Accelerated"); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); vbox = gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); gtk_container_add (GTK_CONTAINER (frame), vbox); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); vbox2 = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5); label = gtk_label_new ("Value :"); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0); adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0, 0.5, 100.0, 0.0); spinner1 = gtk_spin_button_new (adj, 1.0, 2); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE); gtk_widget_set_size_request (spinner1, 100, -1); gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0); vbox2 = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5); label = gtk_label_new ("Digits :"); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0); adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 5, 1, 1, 0); spinner2 = gtk_spin_button_new (adj, 0.0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner2), TRUE); g_signal_connect (G_OBJECT (adj), "value_changed", G_CALLBACK (change_digits), (gpointer) spinner2); gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); button = gtk_check_button_new_with_label ("Snap to 0.5-ticks"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (toggle_snap), (gpointer) spinner1); gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); button = gtk_check_button_new_with_label ("Numeric only input mode"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (toggle_numeric), (gpointer) spinner1); gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); val_label = gtk_label_new (""); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); button = gtk_button_new_with_label ("Value as Int"); g_object_set_data (G_OBJECT (button), "user_data", val_label); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (get_value), GINT_TO_POINTER (1)); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); button = gtk_button_new_with_label ("Value as Float"); g_object_set_data (G_OBJECT (button), "user_data", val_label); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (get_value), GINT_TO_POINTER (2)); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0); gtk_label_set_text (GTK_LABEL (val_label), "0"); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0); button = gtk_button_new_with_label ("Close"); g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (window)); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); gtk_widget_show_all (window); /* Входим в завершающий цикл */ gtk_main (); return 0; }

<<< Previous

Home

Next >>>

Text Entries

Up

Combo Box