Gtk+, Glade3, Anjuta 编程开发小结

转 自:http://blog.chinaunix.net/u3/100915/showart_2158659.html

 

 

开发系统:

  Ubuntu Release 9.10(Karmic)

1.Gtk+简介

    Gtk+采用的是LGPL协议的自由软件包,是GNU项目的一部分。它是两大跨平台GUI toolkit之一,另一个是QT,但是QT并不是所有的版本都是开源的,分为开源版和商业版。 Linux流行的GNOME桌面环境采用的就是Gtk+ 开发的,Google的Linux版Chrome浏览器也是基于Gtk+开发的。 Gtk+提供了几乎所有流行开发语言(如 C++,Python,C#,Java等)的绑定包,但是其native语言还是C。C也是操作系统的编写语言,Linux,Windows都是用C编写 出来的。

    Gtk+在Windows世界里相当于MFC或WPF。

2.LGPL 与GPL协议

    这是Linux软件最常使用的两种开源协议,当然还有其它的BSD,Apache,MIT。

    GPL全称是General Public License,Linux采用的就是GPL协议,一旦使用了含有GPL协议的代码或类库,本身也必需开源,这是所谓的传染性。

    LGPL是Lesser GPL,比GPL宽松的协议,采用了LGPL代码的软件可以是闭源的。底层的类库一般就采用LGPL协议,如Gtk+和开源版的QT。

    有意思的是,2009年很多公司并没有遵守GPL等开源协议:

  • 微软Windows 7的USB/DVD下载安装工具使用了GNU的代码,一开始并没有开放源码,在Open Source人士的强烈抗议之后,重新发布了该工具的开源版本。

  • 射手播放器项目公开谴责腾讯的QQ影音违反开源协议。在11月份,腾讯被 ffmpeg发现并列入耻辱版。腾讯是一家全球IT市值排名17的公司,大陆唯一一个入围全球IT市值20强的公司。

  • 软件自由法律中心起诉百思买集团,三星电子美国,西屋电子,JVC美国,西部数 据,台湾合勤科技违反GPL等。

  • aMule作者要求VeryCD开源,指出VeryCD是以aMule为基础构 建的。

  • ”绿霸“被指责使用了OpenCV的haar分类过滤器,却没有遵守 OpenCV的BSD协议,在版权信息中加入BSD许可证。

3.Glade3介绍

     Glade是为Gtk+和GNOME开发出来的UI快速开发工具,它的全称是Glade Interface Designer。

     它包含了Button,Label,Radio等所有控件,对齐方式以及设置消息函数。Glade3文件是一个纯XML描述的文件,Glade3版本 之前,据说可以直接转成代码.h和.c。但是Glade3已经去掉这个功能了,为了UI设计跟代码完全分离出来,也比较符合现代编程思想和风格。

     Glade3在Windows里相当与Blend2,它可以设计出WPF的UI。其中Blend2也是用XML描述的,叫XAML语言或文件。

     使用Glade3的一点注意事项:

    一开始建立的Windows窗口需要使用Contaner面板里面的一个Fixed功能先固定住,这样再添加其它控件的时候比较方便,不会出现一个 Button覆盖住一个Windows窗口的情况,并且无法调节其大小。如果固定住Windows窗口,点击正中间上方的Drag and Resize就可以拖动了。

4.安装Gtk+编程的依赖包

    // Anjuta IDE

    sudo apt-get install anjuta

    // Build tools

    sudo apt-get install autogen automake build-essential indent intltool 

    sudo apt-get install gnome-core-devel 

    sudo apt-get install pkg-config

    // Help documents
    sudo apt-get install devhelp 
    sudo apt-get install libglib2.0-doc libgtk2.0-doc 

    // Glade
    sudo apt-get install glade libglade2-dev

    // Gtk+ for C++

    sudo apt-get install libglademm-2.4-dev libgnomemm-2.6-dev intltool
    sudo apt-get install libgtkmm-2.4-doc libcairomm-1.0-doc libglib2.0-doc libgnome2-doc libsigc++-2.0-doc

5.命令行编译与makefile
  • 测试Gtk+的编译环境,新建一个base.c的空文档,插入以下代码。

      #include <gtk/gtk.h>
      int main( int argc, char *argv[] ) 
     { 
         GtkWidget *window=NULL; 
         gtk_init (&argc, &argv); 
         window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
         gtk_widget_show (window); 
         gtk_main ();
         return 0;
      }

      打开终端,进入base.c的当前文件目录,运行下面的gcc命令:

            gcc base.c -o base `pkg-config --cflags --libs gtk+-2.0`

       则生成一个base的可执行文件,运行./base,测试运行结果,可以看见一个窗口界面。表明Gtk+开发环境配置正确。

  • 也可以将编译、链接命令写成 makefile,如下:

    CC = gcc
            all:
            $(CC) base.c -o base `pkg-config --cflags --libs gtk+-2.0`

          在终端直接运行make 命 令,就可以生产base 的可执行文件。

6.Anjuta IDE编程

  6.1 测试Anjuta的环境

     1. 新建Gtk+工程

        File → New → Project → C → Gtk+2.0

        Anjuta为我们创建了一个包含所有文件的文件夹。

     2.打开Src文件夹,包含了 main.c和gtk_foobar.ui这两个常要用到的文件,以及callbacks.c和callbacks.h,Makefile.am文件。

       从create_window()函数里的代码可以看 出,*.ui是用GtkBuilder的gtk_builder_add_from_file()来读取的。

      builder = gtk_builder_new ();

      if (!gtk_builder_add_from_file (builder, UI_FILE, &error))
     {
          g_warning ("Couldn't load builder file: %s", error->message);
          g_error_free (error);
     }

      3. 点击Build菜单,编译main.c文件和prjoct文件。Build成功后,再打开Run菜单,执行Execute,生产一个名字为Windows 的窗口。这就是默认的Gtk+窗口。

   6.2 编写一个UI界面,含Menu,Button,Label控件,实现Button的Click事件响应。

       Menu是通过加入MenuBar控件,在小窗口的树状层次结 构,右键点击Edit来添加子菜单。

       Button,Label是直接脱控件实现。给 Menu,Buton,Label取好名字就可以了,便于编程理解。

  6.3 添加为名为button_Up的Button的Click响应:

  Step 1:

    在button属性的页面,选Signals标签,在 GtkButton的clicked属性添加名为button_Up_clicked_cb()的call back 函数,anjuta会在main.c中添加一个空函数。

  Step 2:

     在create_window()函数里建立button和label的signal_connect连接:

    // Get label_Status object

   GObject* label_Status_obj = gtk_builder_get_object(builder, "label_Status");

    // Get button objects

    GObject* button_Up_obj = gtk_builder_get_object(builder, "button_Up");

    // Connect signals (buttons --> label)

    g_signal_connect (button_Up_obj, "clicked", G_CALLBACK(button_Up_clicked_cb), label_Status_obj);

    g_signal_connect()函数里,将label_Status作为user data传递过去。

 Step 3:

  在click函数里处理事件:

  void

  button_Up_clicked_cb (GtkButton *self, gpointer user_data)

  {

  GtkWidget* labelForStatus = GTK_WIDGET(user_data);

  gtk_label_set_text(GTK_LABEL(labelForStatus), "Up!");

  }

至此,代码实现已经基本完成,雷同的部分作相应的处理。

7.程序实例
   
    源码在附录。

8.参考文献:
  1. http://en.wikipedia.org/wiki/Gtk%2B
  2. http://www.gtk.org/
  3. http://baike.baidu.com/view/1047410.htm
  4. http://glade.gnome.org/
  5. http://www.awflasher.com/blog/archives/939
  6. 开源时代2010.01(总第十六期)
  7. http://www.freeoa.net/index.php?option=com_content&view=article&id=66:bsd&catid=5:commercepudct&Itemid=2
  8. Devhelp
  9. http://blog.csdn.net/Linuxdianc/archive/2009/12/21/5047600.aspx
  10. https://www.ibm.com/developerworks/cn/views /opensource/libraryview.jsp?type_by=文档库 &view_by=search&search_by=GTK%2B+ 基 础


    附录
    main.c 源码:

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * main.c
 * Copyright (C) alex 2010 <[email protected]>
 *
 * gtk-foobar is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gtk-foobar is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */


# include < sys/ types. h>
# include < sys/ stat. h>
# include < unistd. h>
# include < string . h>
# include < stdio. h>
# include < config. h>
# include < gtk/ gtk. h>

/*
 * Standard gettext macros.
 */

# ifdef ENABLE_NLS
# include < libintl. h>
# undef _
# define _( String ) dgettext ( PACKAGE, String )
# ifdef gettext_noop
# define N_( String ) gettext_noop ( String )
# else
# define N_( String ) ( String )
# endif
# else
# define textdomain( String ) ( String )
# define gettext( String ) ( String )
# define dgettext( Domain, Message) ( Message)
# define dcgettext( Domain, Message, Type) ( Message)
# define bindtextdomain( Domain, Directory) ( Domain)
# define _( String ) ( String )
# define N_( String ) ( String )
# endif

# include "callbacks.h"

/* For testing propose use the local (not installed) ui file */
/* #define UI_FILE PACKAGE_DATA_DIR"/gtk_foobar/ui/gtk_foobar.ui" */
# define UI_FILE "src/gtk_foobar.ui"

void
button_Up_clicked_cb ( GtkButton * self, gpointer user_data) ;
void
button_Middle_clicked_cb ( GtkButton * self, gpointer user_data) ;
void
button_Bottom_clicked_cb ( GtkButton * self, gpointer user_data) ;

GtkWidget*
create_window ( void )
{
    GtkWidget * window;
    GtkBuilder * builder;
    GError* error = NULL ;

    builder = gtk_builder_new ( ) ;
    if ( ! gtk_builder_add_from_file ( builder, UI_FILE, & error ) )
    {
        g_warning ( "Couldn't load builder file: %s" , error - > message) ;
        g_error_free ( error ) ;
    }

    /* This is important */
    gtk_builder_connect_signals ( builder, NULL ) ;
    window = GTK_WIDGET ( gtk_builder_get_object ( builder, "window" ) ) ;


    // Get label_Status object

    GObject* label_Status_obj = gtk_builder_get_object( builder, "label_Status" ) ;
    
    // Get button objects

    GObject* button_Up_obj = gtk_builder_get_object( builder, "button_Up" ) ;
    GObject* button_Middle_obj = gtk_builder_get_object( builder, "button_Middle" ) ;
    GObject* button_Bottom_obj = gtk_builder_get_object( builder, "button_Bottom" ) ;
    

    // Connect signals (buttons --> label)

    g_signal_connect ( button_Up_obj, "clicked" , G_CALLBACK( button_Up_clicked_cb) , label_Status_obj) ;
    g_signal_connect ( button_Middle_obj, "clicked" , G_CALLBACK( button_Middle_clicked_cb) , label_Status_obj) ;
    g_signal_connect ( button_Bottom_obj, "clicked" , G_CALLBACK( button_Bottom_clicked_cb) , label_Status_obj) ;

    g_object_unref ( builder) ;
    
    return window;
}

int
main ( int argc, char * argv[ ] )
{
     GtkWidget * window;

# ifdef ENABLE_NLS
    bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR) ;
    bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" ) ;
    textdomain ( GETTEXT_PACKAGE) ;
# endif
    
    gtk_set_locale ( ) ;
    gtk_init ( & argc, & argv) ;

    window = create_window ( ) ;
    gtk_widget_show ( window) ;

    gtk_main ( ) ;
    return 0;
}

void
button_Up_clicked_cb ( GtkButton * self, gpointer user_data)
{
    GtkWidget* labelForStatus = GTK_WIDGET( user_data) ;
    gtk_label_set_text( GTK_LABEL( labelForStatus) , "Up!" ) ;

}

void
button_Middle_clicked_cb ( GtkButton * self, gpointer user_data)
{
    GtkWidget* labelForStatus = GTK_WIDGET( user_data) ;
    gtk_label_set_text( GTK_LABEL( labelForStatus) , "Middle!" ) ;

}

void
button_Bottom_clicked_cb ( GtkButton * self, gpointer user_data)
{
    GtkWidget* labelForStatus = GTK_WIDGET( user_data) ;
    gtk_label_set_text( GTK_LABEL( labelForStatus) , "Bottom!" ) ;

}

 

gtk_foobar.ui 源码:

< ? xml version = "1.0" ? >
< interface>
  < requires lib= "gtk+" version = "2.16" / >
  < !-- interface-naming-policy project-wide -->
  < object class= "GtkWindow" id= "window" >
    < property name= "visible" > True< / property>
    < property name= "title" translatable= "yes" > Alex Du's Test</property>
    <property name="default_width">499</property>
    <property name="default_height">400</property>
    <signal name="destroy" handler="destroy" object="NULL"/>
    <child>
      <object class="GtkFixed" id="fixed2">
        <property name="visible">True</property>
        <child>
          <object class="GtkButton" id="button_OK">
            <property name="label">gtk-ok</property>
            <property name="width_request">95</property>
            <property name="height_request">39</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="use_stock">True</property>
          </object>
          <packing>
            <property name="x">290</property>
            <property name="y">292</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label_Content">
            <property name="width_request">270</property>
            <property name="height_request">45</property>
            <property name="visible">True</property>
            <property name="label" translatable="yes">This is from Alex Du'
s test!< / property>
          < / object>
          < packing>
            < property name= "x" > 108< / property>
            < property name= "y" > 193< / property>
          < / packing>
        < / child>
        < child>
          < object class= "GtkButton" id= "button_Cancel" >
            < property name= "label" > gtk-cancel< / property>
            < property name= "width_request" > 96< / property>
            < property name= "height_request" > 38< / property>
            < property name= "visible" > True< / property>
            < property name= "can_focus" > True< / property>
            < property name= "receives_default" > True< / property>
            < property name= "use_stock" > True< / property>
          < / object>
          < packing>
            < property name= "x" > 396< / property>
            < property name= "y" > 293< / property>
          < / packing>
        < / child>
        < child>
          < object class= "GtkMenuBar" id= "menubar1" >
            < property name= "width_request" > 97< / property>
            < property name= "height_request" > 34< / property>
            < property name= "visible" > True< / property>
            < child>
              < object class= "GtkMenuItem" id= "menuitem1" >
                < property name= "visible" > True< / property>
                < property name= "label" translatable= "yes" > _Place< / property>
                < property name= "use_underline" > True< / property>
                < child type= "submenu" >
                  < object class= "GtkMenu" id= "menu1" >
                    < property name= "visible" > True< / property>
                    < child>
                      < object class= "GtkImageMenuItem" id= "imagemenuitem1" >
                        < property name= "label" translatable= "yes" > _Up< / property>
                        < property name= "visible" > True< / property>
                        < property name= "use_underline" > True< / property>
                        < property name= "image" > image1< / property>
                        < property name= "use_stock" > False< / property>
                      < / object>
                    < / child>
                    < child>
                      < object class= "GtkImageMenuItem" id= "imagemenuitem2" >
                        < property name= "label" translatable= "yes" > _Middle< / property>
                        < property name= "visible" > True< / property>
                        < property name= "use_underline" > True< / property>
                        < property name= "image" > image2< / property>
                        < property name= "use_stock" > False< / property>
                      < / object>
                    < / child>
                    < child>
                      < object class= "GtkImageMenuItem" id= "imagemenuitem3" >
                        < property name= "label" translatable= "yes" > _Bottom< / property>
                        < property name= "visible" > True< / property>
                        < property name= "use_underline" > True< / property>
                        < property name= "image" > image3< / property>
                        < property name= "use_stock" > False< / property>
                      < / object>
                    < / child>
                  < / object>
                < / child>
              < / object>
            < / child>
          < / object>
          < packing>
            < property name= "x" > 41< / property>
            < property name= "y" > 17< / property>
          < / packing>
        < / child>
        < child>
          < object class= "GtkButton" id= "button_Up" >
            < property name= "label" translatable= "yes" > _Up< / property>
            < property name= "width_request" > 76< / property>
            < property name= "height_request" > 41< / property>
            < property name= "visible" > True< / property>
            < property name= "can_focus" > True< / property>
            < property name= "receives_default" > True< / property>
            < property name= "use_underline" > True< / property>
            < property name= "yalign" > 0. 47999998927116394< / property>
            < signal name= "clicked" handler= "button_Up_clicked_cb" / >
          < / object>
          < packing>
            < property name= "x" > 42< / property>
            < property name= "y" > 65< / property>
          < / packing>
        < / child>
        < child>
          < object class= "GtkButton" id= "button_Middle" >
            < property name= "label" translatable= "yes" > _Middel< / property>
            < property name= "width_request" > 83< / property>
            < property name= "height_request" > 43< / property>
            < property name= "visible" > True< / property>
            < property name= "can_focus" > True< / property>
            < property name= "receives_default" > True< / property>
            < property name= "use_underline" > True< / property>
            < signal name= "clicked" handler= "button_Middle_clicked_cb" / >
          < / object>
          < packing>
            < property name= "x" > 124< / property>
            < property name= "y" > 65< / property>
          < / packing>
        < / child>
        < child>
          < object class= "GtkButton" id= "button_Bottom" >
            < property name= "label" translatable= "yes" > _Bottom< / property>
            < property name= "width_request" > 82< / property>
            < property name= "height_request" > 40< / property>
            < property name= "visible" > True< / property>
            < property name= "can_focus" > True< / property>
            < property name= "receives_default" > True< / property>
            < property name= "use_underline" > True< / property>
            < signal name= "clicked" handler= "button_Bottom_clicked_cb" / >
          < / object>
          < packing>
            < property name= "x" > 213< / property>
            < property name= "y" > 67< / property>
          < / packing>
        < / child>
        < child>
          < object class= "GtkLabel" id= "label_Status" >
            < property name= "width_request" > 109< / property>
            < property name= "height_request" > 42< / property>
            < property name= "visible" > True< / property>
          < / object>
          < packing>
            < property name= "x" > 18< / property>
            < property name= "y" > 292< / property>
          < / packing>
        < / child>
      < / object>
    < / child>
  < / object>
  < object class= "GtkImage" id= "image1" >
    < property name= "visible" > True< / property>
    < property name= "stock" > gtk-missing-image< / property>
  < / object>
  < object class= "GtkImage" id= "image2" >
    < property name= "visible" > True< / property>
    < property name= "stock" > gtk-missing-image< / property>
  < / object>
  < object class= "GtkImage" id= "image3" >
    < property name= "visible" > True< / property>
    < property name= "stock" > gtk-missing-image< / property>
  < / object>
< / interface>

 

 


你可能感兴趣的:(Gtk+, Glade3, Anjuta 编程开发小结)