`
renzhelife
  • 浏览: 668315 次
文章分类
社区版块
存档分类
最新评论

GTK+ learning summary

 
阅读更多
1. about naming coventions
a. All gtk functions or classes(structures) are started with "gtk" or "Gtk" as prefixes. For instance,
gtk_widget_destroy, GtkLabel, GtkWidget. All glib functions or classese are prefixed with g, for example
g_signal_connect, g_ascii_strcasecmp, G_OBJECT, g_object_set, g_object_get
b. The operations for each classes was prefixed by class name. for example, gtk_window_new,
gtk_button_new_with_label. GtkWindow, GtkLabel
.
c. All returning types and arguments are pointers to classes. For example, GtkWidget *gtk_window_new(),
gtk_window_set_title( GtkWindow *window, gchar *str );

d. All constructor of each classes return the pointer to GtkWidget.
e. You can covert types using macros. GtkWidget *window; GtkWindow *window = GTK_WINDOW( window );
f. About signal connecting function, it takes pointer to G_OBJECT only, the final argument gpointer is
the data you wanna pass into event handling function.
g. Some event handling function should look like this:
gboolean event_happened( GtkWidget *widget, GdkEvent *event, gpointer data );
the first arg widget is the widget which received the signal, event is the event and
pointer is the data you want to pass.
Of course, you can use any other form of event handler, like:
void event_handle( GtkWidget *widget, gpointer data );
This event handler is much more popular than others
void event_emitted( GtkWidget *widget1, GtkWidget *widget2 );
the arguments are pointers. Since you can cast a pointer to any other
type, so you can replace GtkWidget with any other kind widget you like. Generally, First arg: widget1 is
the one from which signals are emitted. It is also the widget to which you connect signal. The second
argument of event handler: widget2, also can be casted to other pointers you like. It is passed from
final argument of g_signal_connect.
Sometimes, your handlers must operate more than one widgets. To solve the problem, you can use a structure
which holds all the necessary widgets. You can pass a pointer to such structure into your handler. E.G.

You can connect signal and handler this way:

The handler should look like this:
void button_clicked( GtkButton *button, Data *data );
h.For some operations there are more than one function. We get overloading here. But C does not
support overloading explictly. We solve the problem by adding suffixes to functions indicating
overloading. e.g.: gtk_button_new(), gtk_button_new_with_label( const char *label ),
gtk_button_new_with_mnemonic( const char *mnemonic ). They have the same purpose ---- to create
a new button. Such overloading is quite popular in GTK+.
i. Once you have add some widgets to some containers, you cannot add it to other containers any more.
That's why we have to new a label after adding it to a vbox. Adding a widget to a container is make
the container parent of widget. When releasing the widgets, the child will be released if the parent
is being freed. Problem occurs when releasing widgets if you add a widgets to more than one container.
It could be released twice which is a fatal error. As a result, you can never add one widget to more
than one containers.
j. There are some internal event handler functions such as destroy -- gtk_widget_destroy. So you can
connect them directly to destroy(gtk_main_quit), gtk_widget_destroy. It is the same to write it by
yourself.
k. Many times, some events have happened, though you have not handled that. A font button, for instance,
would keep its last font after being clicked. No matter whether you handle the signal 'font_set', it
would be there until next click. In fact, in your handler, you do nothing but retrieve the current
also last font from the button and set the font to some widgets. Therefore, it is the same business
to retrieve the font when we are about to use it.
2. Tricks about widgets
1. GtkFileChooser, GtkFileChooserDialog, GtkFileChooserButton
when you use those widgets, you should handle signal "file_set" rather than others. "file_set" is the
signal emitted when user do a change of file chooser, i.e. select a file, select another file.
Signal "selection_changed" will be emitted either when user do a change or when a function change
the current path. We should use "selection_changed" to monitor file chooser's change. While "file_set"
is for detecting a file has been selected.
2. GtkWindow
If you want to add asking dialog before closing, you should catch signal "delete_event". And the handler's
prototype should look like this: gboolean before_exit( GtkWidget *, GdkEvent *, gpointer );
returning FALSE if you don't quit, else return TRUE to quit.
3. GtkHBox, GtkVBox
To keep your widgets look homogenous, you have to pack all of them onto boxes. If you pack a hbox and
a check button onto a vbox, the result is unbalanced. So you'd better arrange all your widgets onto
boxes.
4. GtkLabel
In order to arrange some widgets onto right place, you can use some labels with empty text as a
placeholder. You want to arrange a button called "Exit", for instance, on the right-down cornor
of the window, The easiest way to achieve that is place a label unpon button and a label left to
the button.
5. GtkFontButton, GtkColorButton, GtkFileChooserButton, and alike.
They are buttons, right. But they are special buttons. To realize their true mission, you cannot
treat them as buttons. So you should handle the signal 'font_set', 'color_set' or 'file_set' instead
of 'clicked'.
When you are using GtkFileChooserButton, you'd better use event 'selection_change', although it will be
emitted when setting its properties. The event 'selection_changed' will be emitted when you change a
selection -- that is when you click the button, select another directory or file. Event 'file_set',
however, will only be emitted when you click "Others", opening chooser dialog, selecting a file and clicking
"OK" in dialog. So, if you connect event 'file_set' for it, when you click the folders in the button's list,
nothing would change. Example: explorerlist.c
6. GtkToggleButton, GtkRadioButton, GtkCheckButton
You don't have to write handlers for signal 'toggled'. You can test whether it is active (selected)
when using the option. If you write a handler, you have to test whether it is active, too, in order to
set some flag indicating an option.
7. GtkDialog.
Dialog is like a window which can hold many things. You can add basic widgets like labels, buttons.
In addition, you can add GtkAssistant, progress bar, window on it, too. We are happy to say the dialog's
constructor again:
You can use labels from stock like GTK_STOCK_YES, GTK_STOCK_NO, GTK_STOCK_CANCEL, GTK_STOCK_APPLY, etc.
You can also use some responses predefined by GTK+ like: GTK_RESPONSE_YES, GTK_RESPONSE_NO,
GTK_RESPONSE_CANCEL, GTK_RESPONSE_APPLY
, etc. There is a container vbox in dialog structure, so
you can add anything onto it.
We use the responses of dialog to handle different clicks on buttons, say, returning GTK_RESPONSE_YES means
button 'Yes' has been clicked, returning GTK_RESPONSE_CANCEL means button 'cancel' has been clicked. A
typical one is like this:
In general, we would destroy the dialog after clicking one of its buttons by adding:
gtk_widget_destory( dialog );
after handling return values.
At some other times, we want to keep the dialog, because we are not done yet. Some properties panel dialog,
for example, have three buttons, Cancel, OK and Apply. Clicking Cancel will quit the dialog and do nothing.
Click OK will apply current settings and quit the dialog. Clicking Apply, however, will apply the settings,
but don't quit the dialog. For those dialogs, we should put gtk_widget_destroy after GTK_RESPONSE_CANCEL and
GTK_RESPONSE_OK. But for Apply we should use some other tricks --- we have to keep the dialog and get return
values, so a while loop is necessary. We usually do like this:
We will never leave the dialog unitl 'Cancel' or 'OK' is clicked.
8. The event handler for signal 'delete-event' of window must be like this:
static gboolean window_close( GtkWindow *window, GdkEvent *event, gpointer data );
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics