GTK 구성 요소에 대한 미세 조정 버튼

GTK 구성 요소에 대한 미세 조정 버튼

1. 스피너 버튼 소개

  스핀 버튼 위젯은 일반적으로 사용자가 값 범위에서 값을 선택할 수 있도록 하는 데 사용됩니다. 옆에 위로 및 아래로 버튼이 있는 텍스트 입력 상자로 구성됩니다. 특정 버튼을 클릭하면 텍스트 입력란의 값이 일정 범위 내에서 변경됩니다. 텍스트 입력 상자에 특정 값을 직접 입력할 수도 있습니다.
  스핀 버튼 위젯을 사용하면 값에 소수점 이하 자릿수가 없거나 지정할 수 있으며 구성 가능한 방식으로 값을 늘리거나 줄일 수 있습니다. 버튼을 오랫동안 누르고 있으면 도구를 누른 시간에 따라 구성 요소의 값이 빠른 속도로 변경됩니다.
  스피너는 조정 객체를 사용하여 버튼이 취할 수 있는 값의 범위를 유지합니다. 이것은 스피너 위젯을 매우 강력하게 만듭니다.

2. 개체 프로필 조정

  GTK에는 범위 위젯과 같이 마우스나 키보드를 통해 사용자가 조정할 수 있는 다양한 위젯이 있습니다. GtkText 및 GtkViewport와 같이 일부 조정 가능한 속성이 내부에 있는 구성 요소도 있습니다.
  분명히 사용자가 범위 위젯의 값을 조정할 때 응용 프로그램은 값 변경에 응답해야 합니다. 한 가지 방법은 위젯의 조정된 값이 변경될 때 각 위젯이 자체 신호를 발생시켜 새 값을 신호 처리기로 전달하거나 위젯의 내부 데이터 구조에서 위젯의 값을 조회하도록 하는 것입니다. 그러나 이 조정 값을 여러 구성 요소에 동시에 연결하여 하나의 값이 조정되면 다른 구성 요소가 그에 따라 반응하도록 해야 할 수도 있습니다. 가장 확실한 예는 스크롤 막대를 뷰포트에 연결하거나 텍스트 영역을 스크롤하는 것입니다. 각 구성 요소에 조정 값을 설정하거나 가져오는 고유한 방법이 있는 경우 프로그래머는 이러한 서로 다른 구성 요소 간의 변경 사항을 동기화하거나 연관시키기 위해 매우 복잡한 신호 처리 함수를 작성해야 할 수 있습니다.
  GTK는 조정 객체(Adjustment 객체)로 이 문제를 해결합니다. 튜닝 개체는 구성 요소가 아니지만 구성 요소가 튜닝 값 정보를 전달하는 추상적이고 유연한 방법을 제공합니다. 조정 개체의 가장 확실한 용도는 스크롤바 및 스케일 위젯과 같은 범위 위젯에 대한 구성 매개변수 및 값을 저장하는 것입니다. 그러나 조정 개체는 개체에서 파생되기 때문에 일반 데이터 구조 외에 몇 가지 특수 기능이 있습니다. 가장 중요한 것은 프로그램이 조정 가능한 위젯에 대한 사용자 입력에 응답할 수 있을 뿐만 아니라 조정 가능한 위젯 간에 조정 값을 투명하게 전파하는 위젯과 같은 신호를 올릴 수 있다는 것입니다.
  조정 개체의 사용은 다른 많은 위젯에서 찾을 수 있습니다. 진행률 표시줄, 시야각, 스크롤 창 등

  • 미세 조정 버튼에서 조정 개체 기능을 만듭니다.
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_FORWARDGTK_SPIN_STEP_BACKWARD는 증가 매개변수가 0이 아닌 한 증가 매개변수에 의해 지정된 값만큼 구성 요소의 값을 늘리거나 줄입니다. 이 경우 위젯의 값은 연결된 조정 개체의 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();
}

Supongo que te gusta

Origin blog.csdn.net/weixin_44453694/article/details/127520000
Recomendado
Clasificación