GTK+ 2.0 Tutorial |
||
---|---|---|
Miscellaneous Widgets |
Кнопки "карусели" используются для пошагового изменения определенного значения в любом направлении, это похоже на прокручивание. Этот виджет выглядит как две кнопки со стрелками расположенные друг над другом, обычно он располагается сбоку в виджете ввода текста. Нажатие на одну из этих кнопок приводит к прокручиванию значений в ту или в другую сторону. При этом строка ввода может уже содержать определенное значение.
Кнопка "карусель" может иметь изначально нулевое или десятичное значение и выполнять пошаговое увеличение или уменьшение. Удержание одной из кнопок в нажатом состоянии приводит к ускоренному изменению значения, в зависимости от времени удержания.
Кнопки "карусели" используют Adjustment объекты для содержания информации о возможных значениях регулирования. Это делает данный виджет более мощным в использовании.
Вспомните что adjustment widget создаются с помощью функции которая содержит следующую информацию:
GtkObject *gtk_adjustment_new( gdouble value,
gdouble lower,
gdouble upper,
gdouble step_increment,
gdouble page_increment,
gdouble page_size );
|
Эти атрибуты регулирования используются кнопками "карусель" следующим образом:
value: инициализирует значение кнопки "карусель"
lower: меньшее значение регулировки
upper: высшее значение регулировки
step_increment: значение на которое происходит увеличение или уменьшение (increment/decrement) при нажатии на кнопку-1 мыши
page_increment: значение increment/decrement при нажатии на кнопку-2
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;
}
|
Text Entries |
Combo Box |