GTK コンポーネントの微調整ボタン

GTK コンポーネントの微調整ボタン

1. スピナー ボタンの概要

  スピン ボタン ウィジェットは通常、ユーザーが値の範囲から値を選択できるようにするために使用されます。これは、テキスト入力ボックスとその横にある上下ボタンで構成されます。特定のボタンをクリックすると、テキスト入力ボックスの値が一定の範囲内で変化します。テキスト入力ボックスに特定の値を直接入力することもできます。
  スピン ボタン ウィジェットを使用すると、値に小数点以下の桁数を指定しないか、指定することができ、設定可能な方法で値を増減できます。ボタンを長押しすると、押した時間に応じて成分の値が加速度的に変化します。
  スピナーは調整オブジェクトを使用して、ボタンが取り得る値の範囲を維持します。これにより、スピナー ウィジェットが非常に強力になります。

2. オブジェクトのプロファイルを調整する

  GTK には、範囲ウィジェットなど、ユーザーがマウスやキーボードを介して調整できるさまざまなウィジェットがあります。GtkText や GtkViewport など、内部に調整可能なプロパティを備えたコンポーネントもいくつかあります。
  明らかに、ユーザーが範囲ウィジェットの値を調整すると、アプリケーションは値の変更に応答する必要があります。1 つのアプローチは、ウィジェットの調整された値が変化したときに各ウィジェットに独自のシグナルを発生させ、新しい値をシグナル ハンドラーに渡すか、ウィジェットの内部データ構造でウィジェットの値を検索させることです。ただし、1 つの値が調整されると、他のコンポーネントもそれに応じて応答するように、この調整値を同時に複数のコンポーネントに接続する必要がある場合があります。最もわかりやすい例は、スクロールバーをビューポートまたはスクロールするテキスト領域に接続することです。各コンポーネントに調整値を設定または取得するための独自の方法がある場合、プログラマは、これらの異なるコンポーネント間の変更を同期または関連付けるために、非常に複雑な信号処理関数を作成する必要がある場合があります。
  GTK は、調整オブジェクト (Adjustment オブジェクト) を使用してこの問題を解決します。チューニング オブジェクトはコンポーネントではありませんが、コンポーネントがチューニング値の情報を渡すための抽象的かつ柔軟な方法を提供します。調整オブジェクトの最も明白な使用法は、スクロールバーやスケール ウィジェットなどの範囲ウィジェットの構成パラメータと値を保存することです。ただし、調整オブジェクトは Object から派生しているため、通常のデータ構造に加えていくつかの特別な機能があります。最も重要なことは、ウィジェットと同様に、プログラムが調整可能なウィジェットに対するユーザー入力に応答できるだけでなく、調整可能なウィジェット間で調整値を透過的に伝達できるようにするシグナルを生成できることです。
  調整オブジェクトの使用は、他の多くのウィジェットでも見られます。プログレスバー、視野角、スクロールウィンドウなど。

  • 微調整ボタンで調整オブジェクト関数を作成します。
GtkAdjustment *gtk_adjustment_new (gdouble value,
gdouble lower,gdouble upper,
gdouble step_increment,gdouble page_increment,
gdouble page_size);
形参:value -- 微调按钮初始值
      lower、upper  --构件允许的最大值、最小值
      step_increment  --鼠标左键按下构件一次增加/减小的值
      page_increment  --鼠标右键下构件一次增加/减少的值
      page_size  --没有用到
返回值:返回微调按钮构件对象
  • スピナーボタン作成機能:
GtkWidget *gtk_spin_button_new (GtkAdjustment *adjustment,gdouble  climb_rate,guint digits)
形参:adjustment --调整对象
      climb_rate --指明构件数值变化的加速度(长时间按住按钮, 数值会加速变化)。介于0.0~1.0之间
      digits --微调按就值小数位数
  • 微調整ボタンパラメータ設定機能:
void gtk_spin_button_configure( GtkSpinButton *spin_button,GtkAdjustment *adjustment,
gdouble climb_rate,guint digits );
形参:spin_button --微调按钮控件
adjustment --调整对象
      climb_rate --指明构件数值变化的加速度(长时间按住按钮, 数值会加速变化)。介于0.0~1.0之间
      digits --微调按就值小数位数
  • ウィジェットによって内部的に使用される調整オブジェクトを設定または取得します。
/*获取微调按钮调整对象信息*/
GtkAdjustment *gtk_spin_button_get_adjustment (GtkSpinButton *spin_button);
/*设置微调按钮调整对象信息*/
gtk_spin_button_set_adjustment (GtkSpinButton *spin_button,GtkAdjustment *adjustment);
  • スピナー ボタンの小数点以下の桁数を設定します。
void gtk_spin_button_set_digits (GtkSpinButton *spin_button,guint digits)
形参:spin_button --微调按钮控件
      digits --微调按钮数值小数位数
  • スピナー ボタンの値を設定します。
void gtk_spin_button_set_value (GtkSpinButton *spin_button,gdouble value);
形参:spin_button --微调按钮控件
      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 );
形参:spin_button --微调按钮控件
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

  GTK_SPIN_STEP_FORWARDおよびGTK_SPIN_STEP_BACKWARD は、increment パラメーターが 0 でない限り、increment パラメーターで指定された値だけコンポーネントの値を増減します。この場合、ウィジェットの値は、関連付けられた調整オブジェクトの step_increment 値によって変更されます。
  GTK_SPIN_PAGE_FORWARDGTK_SPIN_PAGE_BACKWARD は、インクリメント パラメーターによってスピナー ウィジェットの値を変更するだけです。
  GTK_SPIN_HOME は、ウィジェットの値を、関連付けられた調整オブジェクトの範囲の最小値に設定します。
  GTK_SPIN_END は、ウィジェットの値を、関連付けられた調整オブジェクトの範囲の最大値に設定します。
  GTK_SPIN_USER_DEFINED は、指定された値だけウィジェットの値を変更するだけです。

  • スピナー ウィジェットのテキスト ボックスを値の入力のみに制限します。
void gtk_spin_button_set_numeric (GtkSpinButton *spin_button,gboolean numeric)
形参:spin_button --微调按钮控件
      numeric  --TRUE 只能输入数字;FALSE 可以输入任意内容
  • スピナー ウィジェットを上部と下部の間で循環するように設定します。
void gtk_spin_button_set_wrap (GtkSpinButton  *spin_button, gboolean wrap)
形参:spin_button --微调按钮控件
      wrap --TRUE 当按钮值到达最小值再往下调整将变为最大值;最大值再往上调整将为最小值
            FALSE 当按钮值到达最小值再往下调整将保持不变;最大值再往上调整保持不变

  スピナー ウィジェットの値を最も近い step_increment (スピナー ウィジェットで使用される調整オブジェクトに設定) に丸めるように設定できます。次の関数で実装します。

void gtk_spin_button_set_snap_to_ticks( GtkSpinButton *spin_button,gboolean snap_to_ticks );
  • スピナー ウィジェットの更新方法は、次の関数で変更できます。
void gtk_spin_button_set_update_policy( GtkSpinButton*spin_button,GtkSpinButtonUpdatePolicy policy );
形参:spin_button --微调按钮控件
      policy  --可以取如下值:
		  GTK_UPDATE_ALWAYS 
          GTK_UPDATE_IF_VALID。

GTK_UPDATE_IF_VALIDモード  では、スピナー ウィジェットは、入力テキストが調整オブジェクトの指定された範囲内の有効な値である場合にのみ更新され、それ以外の場合、テキストは現在の値にリセットされます。GTK_UPDATE_ALWAYS
モード   では、テキストを数値に変換する際のエラーは無視されます。

  • スピナー ボタンを更新:
void gtk_spin_button_update( GtkSpinButton *spin_button );

3. スピナーボタンの例

ここに画像の説明を挿入
  この例では、次の関数を実装します。

  1. スピナー ボタンによる数値日付 (年、月、日)。
  2. チェック ボタンを使用してスピナーを選択すると、数字のみを入力できます。
  3. 値の小数点以下の桁数を設定します
  4. 「終了」ボタンを押すと、ダイアログ ボックスで終了するかどうかを確認するメッセージが表示され、「保存」ボタンを押すと、保存が成功したことを確認するメッセージが表示されます。
#include <gtk/gtk.h>
#include <stdio.h>
/*微调按钮回调函数*/
void spin_button_callback(GtkWidget *widget,gpointer data)
{
    
    
	GtkWidget *spinbutton=(GtkWidget *)data;
	int val;
	/*获取当前微调按钮的值*/
	val=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
	g_print("val=%d\n",val);
	/*修改小数位数*/
	gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spinbutton),val);
}
/*复选按钮处理函数*/
void check_button_callback(GtkWidget *widget,gpointer data)
{
    
    
	GtkWidget *spinbutton=(GtkWidget *)data;
	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
	{
    
    
		/*设置微调按钮只能输入数字*/
		gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinbutton),TRUE);
	}
	else
	{
    
    
		/*设置微调按钮可以输入任意内容*/
		gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinbutton),FALSE);
	}
}
/*保存按钮处理函数*/
void save_button_callback(GtkWidget *widget,gpointer data)
{
    
    
	g_print("保存\n");
	GtkWidget *window=(GtkWidget *)data;
	GtkWidget *dialog;
	GtkWidget *label;
	dialog=gtk_dialog_new_with_buttons("保存", GTK_WINDOW(window),GTK_DIALOG_MODAL,NULL);
	gtk_window_set_default_size(GTK_WINDOW(dialog),100, 100);
	label=gtk_label_new("保存成功\n");
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),label,TRUE, TRUE,0);
	gtk_widget_show(label);
	gtk_widget_show(dialog);
}
GtkWidget *dialog;
/*对话框处理回调函数*/
void button_clicked_callback(GtkWidget *widget,gpointer data)
{
    
    
	char *pada=(gchar *)data;
	if(!strcmp(pada,"on"))
	{
    
    
		gtk_widget_destroy(dialog);//关闭对话框
	}
	if(!strcmp(pada,"ok"))
	{
    
    
		gtk_main_quit();
	}
}
/*退出按钮处理函数*/
void quit_button_callback(GtkWidget *widget,gpointer data)
{
    
    
	g_print("退出\n");
	GtkWidget *window=(GtkWidget *)data;
	GtkWidget *label;
	GtkWidget *table;
	GtkWidget *button;
	dialog=gtk_dialog_new_with_buttons("是否退出", GTK_WINDOW(window),GTK_DIALOG_MODAL,NULL);
	gtk_window_set_default_size(GTK_WINDOW(dialog),100, 100);
	label=gtk_label_new("是否退出");
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),label,TRUE, TRUE,0);
	gtk_widget_show(label);

	/*创建组装表*/
	table=gtk_table_new(1,0,FALSE);
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area),table,FALSE, FALSE, 0);
	gtk_widget_show(table);
	/*创建按钮*/
	button=gtk_button_new_from_stock(GTK_STOCK_NO);
	gtk_table_attach_defaults(GTK_TABLE(table),button,0,1,0,1);
	gtk_widget_show(button);
	g_signal_connect(GTK_OBJECT(button),"clicked",G_CALLBACK(button_clicked_callback),"on");
	/*创建按钮*/
	button=gtk_button_new_from_stock(GTK_STOCK_OK);
	gtk_table_attach_defaults(GTK_TABLE(table),button,1,2,0,1);
	g_signal_connect(GTK_OBJECT(button),"clicked",G_CALLBACK(button_clicked_callback),"ok");
	gtk_widget_show(button);
	gtk_widget_show(dialog);
}
int main(int argc,char *argv[])
{
    
    
	GtkWidget *window;
	GtkWidget *vbox,*box;
	GtkWidget *frame;
	GtkAdjustment *adjust;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *spin_button,*spin_val_button;
	GtkWidget *check_button;
	GtkWidget *button;
	gtk_init(&argc,&argv);
	window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window), "微调按钮");
	gtk_window_set_default_size(GTK_WINDOW(window),320, 240);
	gtk_container_set_border_width(GTK_CONTAINER(window) ,5);
	g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

	/*创建纵向盒*/
	vbox=gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width(GTK_CONTAINER(vbox) ,2);
	gtk_container_add(GTK_CONTAINER(window),vbox);
	gtk_widget_show(vbox);
	/*创建框架构件*/
	frame=gtk_frame_new("日期设置");
	gtk_frame_set_label_align(GTK_FRAME(frame),1.0,0.5);
	/*设置框架构件风格*/
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
	gtk_box_pack_start(GTK_BOX(vbox),frame, FALSE,TRUE,0);
	gtk_widget_show(frame);

	/*创建组装表*/
	table=gtk_table_new(2,3,FALSE);
	gtk_container_add(GTK_CONTAINER(frame),table);
	/*设置列之间的间隔*/
	gtk_table_set_col_spacings(GTK_TABLE(table),20);
	gtk_widget_show(table);

	/*创建调整对象*/
	adjust=(GtkAdjustment *)gtk_adjustment_new(2022,1970,3000,1,1,0);
	/*创建微调按钮*/
	spin_button=gtk_spin_button_new(adjust,0.5, 0);
	/*限制微调按钮只能输入数值*/
	gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_button),TRUE);
	/*设置按钮达到最大值后再变为最小值*/
	gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(spin_button), TRUE);
	gtk_table_attach_defaults (GTK_TABLE(table),spin_button,0,1,1,2);
	gtk_widget_show(spin_button);
	/*设置标签*/
	label=gtk_label_new("年");
	gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,0,1);
	
	gtk_widget_show(label);

	/*创建微调按钮*/
	adjust=(GtkAdjustment *)gtk_adjustment_new(1,1,12,1,1,0);
	spin_button=gtk_spin_button_new(adjust,1, 0);
	gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(spin_button), TRUE);
	gtk_table_attach_defaults (GTK_TABLE(table),spin_button,1,2,1,2);
	gtk_widget_show(spin_button);
	/*设置标签*/
	label=gtk_label_new("月");
	gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,0,1);
	gtk_widget_show(label);

	/*创建微调按钮*/
	adjust=(GtkAdjustment *)gtk_adjustment_new(1,1,31,1,1,0);
	spin_button=gtk_spin_button_new(adjust,0.5, 0);
	gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(spin_button), TRUE);
	gtk_table_attach_defaults (GTK_TABLE(table),spin_button,2,3,1,2);
	gtk_widget_show(spin_button);
	/*设置标签*/
	label=gtk_label_new("日");
	gtk_table_attach_defaults(GTK_TABLE(table),label,2,3,0,1);
	gtk_widget_show(label);

	/*创建框架构件*/
	frame=gtk_frame_new("数值调整");
	gtk_frame_set_label_align(GTK_FRAME(frame),0.5,0.5);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
	gtk_box_pack_start(GTK_BOX(vbox),frame, FALSE,TRUE,0);
	gtk_widget_show(frame);
	/*创建纵向向盒*/
	box=gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(frame),box);
	gtk_widget_show(box);
	/*创建组装表*/
	table=gtk_table_new(2,2,FALSE);
	gtk_box_pack_start(GTK_BOX(box),table,TRUE,TRUE,0);
	/*设置列之间的间隔*/
	gtk_table_set_col_spacings(GTK_TABLE(table),10);
	gtk_widget_show(table);	
	/*创建调整对象*/
	adjust=(GtkAdjustment *)gtk_adjustment_new(0,-5000,5000,0.5,0.5,0);
	spin_val_button=gtk_spin_button_new(adjust,0.5, 2);
	gtk_table_attach_defaults (GTK_TABLE(table),spin_val_button,0,1,1,2);
	gtk_widget_show(spin_val_button);
	/*设置标签*/
	label=gtk_label_new("数值");
	gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,0,1);
	gtk_widget_show(label);

	/*创建调整对象*/
	adjust=(GtkAdjustment *)gtk_adjustment_new(2,0,6,1,1,0);
	spin_button=gtk_spin_button_new(adjust,0.5, 0);
	g_signal_connect(G_OBJECT(spin_button),"value_changed",G_CALLBACK(spin_button_callback), spin_val_button);
	gtk_table_attach_defaults (GTK_TABLE(table),spin_button,1,2,1,2);
	gtk_widget_show(spin_button);
	/*设置标签*/
	label=gtk_label_new("小数位数");
	gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,0,1);
	gtk_widget_show(label);

	/*创建复选按钮*/
	check_button=gtk_check_button_new_with_label("仅输入数字");
	gtk_box_pack_start(GTK_BOX(box),check_button,FALSE,FALSE,0);
	g_signal_connect(G_OBJECT(check_button),"toggled",G_CALLBACK(check_button_callback), spin_button);
	gtk_widget_show(check_button);

	/*创建横向盒*/
	box=gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(vbox),box,TRUE,TRUE,0);
	gtk_widget_show(box);
	
	/*创建保存按钮*/
	button=gtk_button_new_with_label("退出");
	gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
	g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(quit_button_callback),window);
	gtk_widget_show(button);
	
	/*创建保存按钮*/
	button=gtk_button_new_with_label("保存");
	gtk_box_pack_end(GTK_BOX(box),button,FALSE,FALSE,0);
	g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(save_button_callback),window);
	gtk_widget_show(button);
	gtk_widget_show(window);
	gtk_main();
}

おすすめ

転載: blog.csdn.net/weixin_44453694/article/details/127520000