- 论坛徽章:
- 0
|
现在可以测试刚才所做的工作。在/src输入make重新编译。如果没有打字或其它错误, make不会显示任何错误信息。运行gtemp检查我们所做的工作。
现在我们开始编写后端。这个很简单,不过在一个复杂的程序里,可能有几个辅助的 文件,绝大多数后端不会放在callbacks.c,比如在gtemp里.
最后使Gtemp能够转换温度单位
目前在callbacks.c里应该有四个空的回调函数。其中两个on_properties1_activate() 和on_preferences1_activate(),现在用不到。使用剩下的 on_fahr_entry_activate()和on_cel_entry_activate()。
我们将要编写一个函数叫做compute_temp(),它将被这两个 entry_activate回调函数调用。定义两个标志, C_TO_F和F_TO_C以便我们知道正在进行哪种转换。 Compute_temp()以调用的控件、用户输入的温度和转换类型做为参数。
在文件头部,在其它#define下面加入这几行
#define C_TO_F 0
#define F_TO_C 1
void compute_temp(GtkWidget *this_widget, float temperature, int type);
这是这些函数和标志的声明。
在文件尾部,所有回调函数的下面,加入这个函数:
void compute_temp(GtkWidget *this_widget, float temperature, int type)
{
GtkWidget *other_entry = NULL;
float result = 0.0;
gchar *result_string = NULL;
switch(type) {
case C_TO_F:
result = ((9.0 / 5.0) * temperature) + 32.0;
other_entry = lookup_widget(this_widget, "fahr_entry");
break;
case F_TO_C:
result = (5.0 / 9.0) * (temperature - 32.0);
other_entry = lookup_widget(this_widget, "cel_entry");
break;
}
result_string = g_strdup_printf("%5.2f", result);
gtk_entry_set_text(GTK_ENTRY(other_entry), result_string);
g_free(result_string);
}
单步执行这个函数,它声明了正确的变量,进入了一个分支语句,在这个语句中温度单位的转换取决于传入了哪个文本框:other_entry = lookup_widget(this_widget, "cel_entry"); and other_entry = lookup_widget(this_widget, "fahr_entry"); 使用glade支持函数lookup_widget() 找到没有用户输入的那个文件框。Gtk_entry只接收文本,因此我们把浮点数通过 g_strdup_printf()转换成文本。这个功能很象printf() 函数,不管字符串有多长都能确保分配了足够的内存。接下来用gtk_entry_set_text() 把结果写入gtk_entry控件。用g_free()释放我们用 g_strdup_printf()创建的结果字符串。
所有的这些函数都可以在gnome.org上API部分查到。GtkEntry详细信息请看 这页。 你可以在这里 查到Glib字符串功能。
还需要在entry_activate里写入代码来实际运行compute_temp函数。找到回调函数名为 on_fahr_entry_activate() 加入以下代码:
gchar *fahr = NULL;
fahr = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
compute_temp(GTK_WIDGET(entry), atof(fahr), F_TO_C);
这儿我们没有做 任何错误检查,只是用atof()把字符串fahr转换成浮点数。后面我们会加入错误检查。找到on_cel_entry_activate()函数,加入以下代码:
gchar *celsius = NULL;
celsius = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
compute_temp(GTK_WIDGET(entry), atof(celsius), C_TO_F);
同样,我们后面会加入错误检查。注意在每一个代码片断我们使用GtkEditable代替GtkEntry。这是因为GtkEntry某些方面不推荐使用(在 Gtk+-1.0,不过在2.0中以恢复了entry_get_text 函数),特别是gtk_entry_get_text()函数。由于GtkEntry是GtkEditable的一个子类,用GtkEditable函数是比较有效的。我们只要记住用GTK_EDITABLE()转换宏把它 转换成一个新类。
现在,我们有一个可用的程序
重新编译看看。在/src子目录输入make,修改任何可能的打字错误,运行程序。如果你在文本框只输入数字,它会运行得很好。试着在其中一个文本框里输入'abc'。它给出了一个结果,因为atof()函数强行把"abc"转换成一个浮点数,不过我们知道结果是错的。如果这个程序只是自己用,而且你知道输入什么才能得到正确结果(象大多数编程者那样),那我们现在就停下来。不过让我们更进一小步,加入 简单的错误检查和提示。
加入错误提示
我们要写另一个函数check_temperature_value(),它将检查以确保输入的数值是数值型而不是其它。这个函数同样也被两个entry_activate函数调用,向程序 状态条输出一条错误信息。
在callbacks.c文件的底部加入函数:
gint check_temperature_value(GtkWidget *this_widget, gchar *value)
{
GtkWidget *appbar;
gint num = 0;
gchar this_char = '';
this_char = *value;
if (!this_char)
return 0;
while (this_char != '') {
if (!isdigit(this_char)) {
/* set up the error message */
appbar = lookup_widget(GTK_WIDGET(this_widget), "appbar1");
gnome_appbar_push(GNOME_APPBAR(appbar), "Please enter numbers only");
return 0;
} else {
num++;
this_char = value[num];
}
}
return 1;
}
我们需要在entry_activate回调函数调用这个函数。加入以下这些行到 on_cel_entry_activate()中,在compute_temp() 函数调用之前:
if (!check_temperature_value(GTK_WIDGET(entry), celsius))
return;
clear_appbar(GTK_WIDGET(entry));
把同样的行加入到 on_fahr_entry_activate()中,在 compute_temp()函数调用之前:
if (!check_temperature_value(GTK_WIDGET(entry), fahr))
return;
clear_appbar(GTK_WIDGET(entry));
最后我们需要clear_appbar()函数。它只是在输入是个正确的数字时从状态条上消除 错误信息。把它加入callbacks.c文件的最后:
void clear_appbar(GtkWidget *this_widget)
{
GtkWidget *appbar;
appbar = lookup_widget(GTK_WIDGET(this_widget), "appbar1");
gnome_appbar_clear_stack(GNOME_APPBAR(appbar));
}
不要忘了在文件头部附近加入两个函数头。编译程序,现有你有一个能工作、错误检查并发出信息的Gtemp版本! |
|