Signal and callback functions of GTK

Signal and callback functions of GTK

  In version 2.0, the signal system was moved from GTK to GLib, so function and type declarations are prefixed with "g_" instead of "gtk_".
  GTK is an event-driven toolkit, meaning it waits in gtk_main() until the next event occurs before passing control to the appropriate function. The transfer of control is done using the "signal" method. (Note that signals here are not equivalent to, and not implemented with, Unix signals, although the terminology used is the same.)

1. Commonly used signals

  Components can send various signals. Signals can be caused by user operations or generated by function simulation events. The common signals are as follows.

member Signal significance generate signal function
windows “destroy” This signal is emitted when the window is closed
button “clicked” Click on the button, which is a combination of press and release actions gtk_button_clicked(button)
“enter” mouse over button gtk_button_enter(button)
“leave” mouse leave button gtk_button_leave(button)
“pressed” Push the button gtk_button_pressed(button)
“released” release button gtk_button_released(button)
toggle_button “toggled” switch button
listbox “select” listbox is selected
“selection_changed” listbox selection is changed
GTKRadioMenuItem “activate” menu option selected

  The two basic mechanisms of GTK+ are the delete_event event and the destroy signal . When the window is about to be closed, the delete_event event appears. When the window is closed, the destroy signal is emitted. For the delete_event event, the top-level window should have a corresponding callback function. Because delete_event means that the user needs to close the application software. Adding a callback function for the delete_event signal involves two steps.
  The callback function for delete_event should return a boolean indicating whether closing the window is allowed. Returning a value of TRUR keeps the window open, and returning a value of FALSE indicates that the window can be closed. If the window is closed, then a destroy signal is sent to tell the application that the window is about to be closed.

2. Signal connection and processing function

2.1 Signal connection function g_signal_connect

 /* 信号连接函数*/
#define g_signal_connect(instance, detailed_signal, c_handler, data)
形参:instance  --void*指针,要发出信号的构件
detailed_signal  -- char *指针,连接的信号的名称
      c_handler  --信号被捕获时所要调用的函数
      data   -- void*指针,传递给信号处理函数(回调函数)的数据
返回值:gulong类型,返回识别回调函数的标识
第三个参数即回调函数一般形式如下:
void callback_func( GtkWidget *widget,gpointer callback_data );
形参:widget -- 指向发出信号的构件的指针
      callback_data  --g_signal_connect传入的参数
注意:上面回调函数的声明只是一般的形式, 有些构件的特殊信号会用不同的调用参数。

  Each signal and each object can have multiple callback functions, and they will run sequentially in the order they are set.

2.2 g_signal_connect return value

  The return value of the signal connection function g_signal_connect is of glong type, which returns a flag identifying the callback function. Because each signal and each object can have multiple callback functions, and they will run sequentially in the order they are set. Therefore, through this return flag, the implemented callback function can be deleted through the following function:

g_signal_handler_disconnect(gpointer instance, gulong handler_id)

  So, you can disconnect a signal handler by passing the component on which you want to remove the handler, and an identifier returned by a signal_connect function.
  Functions such as g_signal_handler_block() and g_signal_handler_unblock() can also be used to temporarily disconnect signal handlers.

void g_signal_handler_block (gpointer instance, gulong handler_id);
void g_signal_handlers_block_by_func( gpointer object,GCallback func,gpointer data );
void g_signal_handler_unblock (gpointer instance,gulong   handler_id);
void g_signal_handlers_unblock_by_func( gpointer object,GCallback func,gpointer data );

2.3 Signal connection function g_signal_connect_swapped

/*信号连接函数*/
#define g_signal_connect_swapped(instance, detailed_signal, c_handler, data)
g_signal_connect_swapped()g_signal_connect() 相同,只是回调函数只用一个参数,一个指向GTK对象的指针。所以当使用这个函数连接信号时,回调函数应该是这样的形式:
	void callback_func( GtkObject *object );

  The purpose of having two functions to set up the signal connection is simply to allow callback functions to have different numbers of arguments. Many functions in the GTK library only accept a single component pointer as its parameter, so for these functions you will use g_signal_connect_swapped(), whereas for functions you define yourself, you may need to provide additional data to your callback function.

3 events

  In addition to the signal mechanism, there is also a set of events reflecting the X event mechanism. Callback functions can be attached to these events.

• event
• button_press_event
• button_release_event
• scroll_event
•motion_notify_event
• delete_event
• destroy_event
• expose_event
• key_press_event
• key_release_event
• enter_notify_event
• leave_notify_event
• configure_event
• focus_in_event
• focus_out_event
• map_event
• unmap_event
• property_notify_event
• selection_clear_event
• selection_request_event
• selection_notify_event
• proximity_in_event
• proximity_out_event
• visibility_notify_event
• client_event
• no_expose_event
• window_state_event

  To connect a callback function to one of these events, you use the function g_signal_connect(), as described above, with one of the above event names as the detailed_signal parameter. Event callback functions are slightly different from signal callback functions:

gint callback_func( GtkWidget *widget,GdkEvent *event,gpointer callback_data );

  GdkEvent is a C union structure whose type depends on which of the above events occurred. To let us know which event occurred, each possible type has a type member that reflects the event that occurred. The rest of the event structure will depend on the type of this event. Possible values ​​for type are:

GDK_NOTHING
GDK_DELETE
GDK_DESTROY
GDK_EXPOSE
GDK_MOTION_NOTIFY
GDK_BUTTON_PRESS
GDK_2BUTTON_PRESS
GDK_3BUTTON_PRESS
GDK_BUTTON_RELEASE
GDK_KEY_PRESS
GDK_KEY_RELEASE
GDK_ENTER_NOTIFY
GDK_LEAVE_NOTIFY
GDK_FOCUS_CHANGE
GDK_CONFIGURE
GDK_MAP
GDK_UNMAP
GDK_PROPERTY_NOTIFY
GDK_SELECTION_CLEAR
GDK_SELECTION_REQUEST
GDK_SELECTION_NOTIFY
GDK_PROXIMITY_IN
GDK_PROXIMITY_OUT
GDK_DRAG_ENTER
GDK_DRAG_LEAVE
GDK_DRAG_MOTION
GDK_DRAG_STATUS
GDK_DROP_START
GDK_DROP_FINISHED
GDK_CLIENT_EVENT
GDK_VISIBILITY_NOTIFY
GDK_NO_EXPOSE
GDK_SCROLL
GDK_WINDOW_STATE
GDK_SETTING

  So, to wire a callback function to one of these events, we would use:

g_signal_connect (G_OBJECT (button), "button_press_event",G_CALLBACK (button_press_callback), NULL);

  It is assumed here that button is a button widget. Now, when the mouse is over the button and the mouse is pressed, the function button_press_callback() is called. This function should be declared as:

static gint button_press_callback( GtkWidget *widget,
						GdkEventButton *event,
						gpointer data );

  Note that we can declare the second parameter type as GdkEventButton, because we know which type of event will occur.
  The return value of this function indicates whether the event should be propagated further by the GTK event handling mechanism. Returning TRUE indicates that this event has been handled and should not be propagated further. Return FALSE to continue normal event processing.

3.1 Example of closing the window with the button connection signal

#include <gtk/gtk.h>
void hello(GtkWidget *widget,gpointer data)
{
    
    
	g_print("按键信号触发成功\n");
}
/*事件处理回调函数*/
gint delete_event(GtkWidget *widget,GdkEvent *evnet,gpointer data)
{
    
    
	g_print("事件处理回调函数调用成功\n");
	return TRUE;//TRUE表示继续,FALSE表示关闭
}

void destroy(GtkWidget *widget,gpointer data)
{
    
    
	g_print("销毁窗口\n");
	gtk_main_quit();//退出程序
}
int main(int argc,char *argv[])
{
    
    
	GtkWidget *window;
	GtkWidget *button;
	/*gtk初始化*/
	gtk_init(&argc, &argv);
	/*创建窗口*/
	window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window),"GTK");/*设置窗口标题*/
	/*信号连接函数*/
	g_signal_connect(GTK_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL);
	g_signal_connect(GTK_OBJECT(window),"destroy", G_CALLBACK(destroy), NULL);
	/*设置容器对象属性:设置窗口边框宽度为100*/
	gtk_container_set_border_width(GTK_CONTAINER(window),100);
	/*创建新的按钮,设置按钮信息为hello*/
	button=gtk_button_new_with_label("hello");
	g_signal_connect(GTK_OBJECT(button),"clicked",G_CALLBACK(hello),NULL);
	g_signal_connect_swapped(GTK_OBJECT(button),"clicked",G_CALLBACK(gtk_widget_destroy),GTK_OBJECT(window));
	/*将按钮放入窗口中*/
	gtk_container_add(GTK_CONTAINER(window),button);
	/*显示控件*/
	gtk_widget_show_all(window);
	/*等待事件*/
	gtk_main();
	return 0;
}

insert image description here

  • Program running effect:

  When we press the hello button with the mouse, the button sends a clicked signal, triggers the hello callback function, and then calls the next signal processing function gtk_widget_destroy(), passes the window component parameters to this function, destroys the window, and the window sends a destroy signal, and then calls We implement the callback function destroy() of the number to realize the program exit.

Guess you like

Origin blog.csdn.net/weixin_44453694/article/details/127372355