|
楼主 |
发表于 2003-7-1 16:59:31
|
显示全部楼层
第3,4节
==============================================================================
3. 联编(Building) Glade生成的C代码
=========================================
3.1 如何联编Glade生成的代码?
联编生成的C代码需要automake版本 >= 1.4以及autoconf版本 >= 2.13。
如果打开gettext支持,还需要gettext版本 >= 0.10.35。
README文件中'Requirements'节有相关的链接。
在工程的根目录下运行'./autogen.sh'来启动
automake、autoconf和相关的程序来产生Makefiles文件。configure的任何
选项都可以直接写在./autogen.sh后面,比如:
./autogen.sh --prefix /usr/local/gnome
接下来运行'make'来创建你自己的程序。
注意: 如果是GNOME程序,必须再运行'make install',这样位图文件可以被正确地安装。
不然,程序可以运行但看不到位图。
3.2 出现错误信息:
aclocal: configure.in: 10: macro `AM_PATH_GTK' not found in library
这条错误信息的意思是找不到gtk.m4文件。(gtk.m4文件是一套m4的宏,
是GTK+的一部分,用来创建GTK+程序。)
aclocal程序(automake程序的一部分)查找宏并加到程序根目录下的aclocal.m4文件中。
想知道GTK+安装在哪里,运行 'gtk-config --prefix'即可。
gtk.m4文件应该在'share/aclocal'子目录下。
想知道aclocal程序使用的目录,可以运行 'aclocal --print-ac-dir'。
应该把GTK+ m4文件的安装目录加入到ACLOCAL_FLAGS环境变量中,
比如:如果GTK+ m4文件在目录/usr/local/share/aclocal中,
在$HOME/.profile文件中加入以下内容:
export ACLOCAL_FLAGS="-I /usr/local/share/aclocal/"
3.3 出现错误信息:
** CRITICAL **: file glade_gnome.c: line 939
(glade_gnome_write_menu_item_source):
assertion `source_buffer != NULL' failed.
在仅仅是GTK+程序中使用GNOME系统菜单项。
编辑所有的菜单确保每个菜单项的"Stock"属性设为"None"。
==============================================================================
4.使用Glade生成的C代码
======================================
4.1 Glade生成了哪些文件?
以下是一些缺省的输出文件,如果你改变了工程选项,文件名称可能有所不同。
autogen.sh - 按正确次序运行automake, autoconf和其它相关程序的脚本文件,
使创建程序更简单。可以把给configure参数直接传递给它。运行
后可以键入 'make'来创建程序。
configure.in - 传递给autoconf的标准脚本,用来产生configure脚本。
Makefile.am - 传递给automake的标准make规则,用来产生Makefile.in文件。
Makefile.in可以被configure脚本转换为Makefile文件。
acconfig.h - 包含一些宏,这些宏在configure脚本中被设置,并加入到
config.h头文件中(在所有源文件中头文件应该是最先被包含进来的)。
gettext支持需要使用到大多数宏(ENABLE_NLS, HAVE_CATGETS,
HAVE_GETTEXT, HAVE_LC_MESSAGES, HAVE_STPCPY),
GNOME则需要HAVE_LIBSM宏 (but it doesn't hurt a GTK+ app),
另一些是由Glade加入的(PACKAGE_LOCALE_DIR, PACKAGE_DATA_DIR,
PACKAGE_SOURCE_DIR).
stamp-h.in - automake用来做为时间戳,以便重新创建出一些已生成的文件。
AUTHORS - 这些文件全是空文件, 以符合GNU的规定。
ChangeLog
NEWS
README
src/Makefile.am - 标准automake文件。
src/main.c - 包含main()主函数,主函数可以创建每一个窗口/对话框。
src/interface.h - 函数声明,调用这些函数可以生成Gladed中创建的窗口和对话框。
src/interface.c - 生成窗口、对话框及其它控件的代码。
src/callbacks.h - 信号及所写回调函数的声明。
src/callbacks.c - 信号处理及回调函数的代码。
src/support.h - 一些支持函数的声明,包括lookup_widget()函数,可以通过这个
函数得到控件的指针。
src/support.c - 支持函数的代码。
如果开启gettext支持, 会创建po子目录,POTFILES.in文件以及一个单独的ChangeLog
文件。POTFILES.in文件列出了包含有可翻译字符串的资源文件,你写的任何资源文件
也要加在里面。
对于GNOME程序,会有macros目录,包含所有用来创建工程的m4宏。(这些宏做为
GNOME的一部分应该已经安装好,但不幸的是在GNOME 1.0.X中并没有这样做。希望在
在GNOME今后的版本中会加以改正,这样就不需要这个目录了)。
*注意*: 如果在创建工程后改变了 'GNOME Support'或 'Gettext Support'工程选项,
则需要更新文件比如configure.in, Makefile.am。最好的解决方法就是在'Project
Options'对话框里改变工程目录,重新创建工程。不过得把加在回调函数的所有代码
拷贝出来。另一个方法是删除autogen.sh, configure.in, Makefile.am, src/Makefile.am,
和src/main.c文件,用Glade重新生成这些文件。不过如果你改变过这些文件,需要再把这些
更改加进去。(希望将来Glade能够改得更好一些。)
4.2 哪些文件可以被安全地修改,哪些会被程序覆盖?
Glade不会覆盖大多数文件。如果联编文件(build files)不存在,它将会重建
这些文件 (相应的工程选项要被设置)。
Glade会覆盖的文件有:
interface.h
interface.c
support.h
support.c
(如果你在工程对话框中更改了这些文件的名称,可能与以上名称不同)
这些文件最顶部会有'DO NOT EDIT'(不要编辑)的信息。
如果你加入或更新了任何信号处理,它们会加入在callbacks.h和callbacks.c文件中。
因此你加入的任何回调函数代码完全安全。如果你改变了一个回调函数的名称,则
需要把删除旧版本并将代码拷到新函数中。
4.3 如何向工程中加入自己的资源文件?
把资源文件(和任何头文件)加入到src/Makefile.am(project1_SOURCES变量的值)中
(假定'project1'是你的工程名称)。
如果使用gettext, 应该同时把资源文件加入到topo/POTFILES.in中,以便能够翻译这些
字符串。
4.4 如何向工程中加入库?
你需要为在工程的configure.in文件中的库加入一个测试,
确认CPPFLAGS变量和LIBS变量已更新为库的说明。(这句不太懂)
(CPPFLAGS变量包含了所有传递给C预处理程序的 -I 标记,
LIBS变量包含了传递给连接器的-l 和 -L 选项)。
autoconf程序提供宏如 AC_CHECK_HEADER和AC_CHECK_LIB,可以
用来检查普通的头文件和库。
许多GTK+和Gnome库提供了配置脚本比如gtk-config,可以输出
所需要的CPPFLAGS和LIBS标记。
例如,libxml提供了一个xml配置脚本,可以象下面那样使用:
dnl Get libxml flags & libs
AC_PATH_PROG(xml_config, xml-config)
if test "x$xml_config" = "x"; then
AC_MSG_ERROR([*** xml-config not found.])
fi
XML_CFLAGS=`$xml_config --cflags 2>/dev/null`
XML_LIBS=`$xml_config --libs 2>/dev/null`
CPPFLAGS="$CPPFLAGS $XML_CFLAGS"
LIBS="$LIBS $XML_LIBS"
注意: 确保把你的configure.in测试放在调用AC_OUTPUT前面。
4.5 在回调函数中如何获得一个控件的指针?
如果有窗口内任一控件的指针,你可以通过调用Glade提供的lookup_widget()函数来获得
窗口内其它控件的指针(在support.c文件中)。
传入参数为窗口内任一控件的指针和想要得到指针的控件名称。通常在信号处理函数中可以
用它的第一个参数做为lookup_widget()函数的第一个参数,例如:
void
on_button1_clicked (GtkButton *button,
gpointer user_data)
{
GtkWidget *entry1;
entry1 = lookup_widget (GTK_WIDGET (button), "entry1");
...
}
注意如果使用libglade,以上代码将不会起作用。相对应的代码应该是:
void
on_button1_clicked (GtkButton *button,
gpointer user_data)
{
GladeXML* xml;
GtkWidget* entry1;
xml = glade_get_widget_tree (GTK_WIDGET (button1));
entry1 = glade_xml_get_widget (xml, "entry1");
...
}
4.6 如何获得另一个窗口中的控件的指针?
需要跟踪所有上层(toplevel)窗口的指针。对于简单的程序,可以用全局变量来存储
这些指针。
对于大多数复杂的程序可以使用gtk_object_set_data()及相关函数来存储在此窗口中
另一个窗口的指针。例如,如果你想创建一个对话框并希望对主窗口中的控件进行操作,
可以这样做:
dialog = create_dialog1 (); /* Call the function generated by Glade. */
gtk_object_set_data (GTK_OBJECT (dialog), "main_window", main_window);
当在对话框代码需要对主窗口进行操作时,可以这样做:
main_window = gtk_object_get_data (GTK_OBJECT (dialog), "main_window");
注意: 必须要很小心地确保这个指针有效。如果这个指针所指向的窗口被销毁,确保再
也不使用这个指针,否则你的程序将会崩溃。
4.7 如何获得GtkOptionMenu的值?
调用gtk_menu_get_active()并传入GtkOptionMenu控件的menu做为参数,可以获得当前
所选菜单项。可以用g_list_index()函数查找到它在菜单中的索引号:
void
on_button1_clicked (GtkButton *button,
gpointer user_data)
{
GtkWidget *option_menu, *menu, *active_item;
gint active_index;
option_menu = lookup_widget (GTK_WIDGET (button), "optionmenu1");
menu = GTK_OPTION_MENU (option_menu)->menu;
active_item = gtk_menu_get_active (GTK_MENU (menu));
active_index = g_list_index (GTK_MENU_SHELL (menu)->children, active_item);
g_print ("Active index: %i\n", active_index);
}
4.8 当GtkOptionMenu值改变时如何调用一个函数?
Glade目前并不支持, 不过你可以手工设置。
创建一个窗口后,获得option menu控件指针,并连接此控件菜单(menu)的"deactivate":
window1 = create_window1 ();
option_menu = lookup_widget (window1, "optionmenu1");
gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (option_menu)->menu),
"deactivate", GTK_SIGNAL_FUNC (on_option_selected),
NULL);
向callbacks.c中加入一个信号处理. 你可以象上一个问题那样获得所选项的索引号(index):
static void
on_option_selected (GtkMenuShell *menu_shell,
gpointer data)
{
GtkWidget *active_item;
gint item_index;
active_item = gtk_menu_get_active (GTK_MENU (menu_shell));
item_index = g_list_index (menu_shell->children, active_item);
g_print ("In on_option_selected active: %i\n", item_index);
}
4.9 如何连接到GtkAdjustment的信号?
Glade目前并不支持,不过你可以象问题3.6(应为4.8)中的一样手工来设置。
创建窗口后,获得包含有adjustment的容器的指针,并连接到
"changed"或"value_changed"信号:
window1 = create_window1 ();
hscale = lookup_widget (window1, "hscale1");
gtk_signal_connect (GTK_OBJECT (GTK_RANGE (hscale)->adjustment),
"changed", GTK_SIGNAL_FUNC (on_adjustment_changed),
NULL);
4.10 窗口显示之前如何向其中的GtkCList控件中加入一行?
用Glade生成的'create' 函数创建一个窗口后,可以使用
lookup_widget()函数获得GtkCList控件指针,并按需要加入行,例如:
GtkWidget *window, *clist;
gchar *row[2]; /* Our GtkCList only has 2 columns. */
window = create_window1 ();
clist = lookup_widget (window, "clist1");
row[0] = "Hello";
row[1] = "World";
gtk_clist_append (GTK_CLIST (clist), row);
row[0] = "Second";
row[1] = "Row";
gtk_clist_append (GTK_CLIST (clist), row);
gtk_widget_show (window1); |
|