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.
typedef struct { GtkWindow *window; GtkLabel *label; GtkButton *button; } Data;
You can connect signal and handler this way:
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( button_clicked ), (gpointer) &data );
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:
GtkWidget *gtk_dialog_new_with_buttons( const char *title, GtkWindow *parent, GtkDialogFlag flag, const char *label_button1, int response_button1, const char *label_button2, int response_button2, ..., NULL ); 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:
int result = gtk_dialog_run( GTK_DIALOG( dialog ) ); if ( result == GTK_RESPONSE_YES ) { /* do something */ } else if ( result == GTK_RESPONSE_NO ) { /* do something */ } 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:
while ( 1 ) { result = gtk_dialog_run( GTK_DIALOG( dialog ) ); if ( result == GTK_RESPONSE_CANCEL ) { /* do something */ gtk_widget_destroy( dialog ); break; } else if ( result == GTK_RESPONSE_OK ) { /* do something */ gtk_widget_destroy( dialog ); break; } else if ( result == GTK_RESPONSE_APPLY ) { /* do something */ } } 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 );
内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值