环境准备

官网下载 GTK 源码包,因为本机 GLib 版本不够,下载一个非最新版的 GTK3.8.0 先学习用

直接阅读 "/gtk+-3.8.0/docs/reference/gtk/html/gtk-building.html" 进行操作

安装完毕,gtk3-demo 出来 gtk 的样例界面即安装搞定

实例学习

编译命令和编译脚本

编译参数包括 pkg-config --libs --cflags gtk+-3.0

为了方便,用脚本管理起来

build.sh

#!/bin/bash
if [ $# -lt 1 ]; then
echo "usage: $0 [xxxx.c]"
exit
fi gcc -o $1_out $1 `pkg-config --libs --cflags gtk+-3.0`

一个简单的HelloWorld按钮

01_simple_button.c

#include <gtk/gtk.h>

// 回调函数1
void hello( GtkWidget *widget, GdkEvent *event, gpointer data )
{
g_print("Hello World\n");
} // 回调函数2
void destroy( GtkWidget *widget, gpointer data )
{
gtk_main_quit();
} gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
/**
* 如果 "delete_event" 信号处理函数
* 返回 FALSE,GTK 会发出 "destroy" 信号
* 返回 TRUE,你不希望关闭窗口
* 当希望弹出 "你确定要退出吗?" 对话框时可以用到
*/
g_print("delete event occurred\n"); return FALSE;
} int main( int argc, char *argv[] )
{
// GtkWidget 是构件的存储类型
GtkWidget *window;
GtkWidget *button; /**
* gtk_init 函数在所有的 GTK 程序都要调用
* 参数由命令行中解析出并填充进来
*/
gtk_init( &argc, &argv ); window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); /**
* 当窗口收到 "delete_event" 信号(该信号由窗口管理器发出,
* 通常是"关闭"选项或是标题栏上的关闭按钮发出的)
* 我们让其调用在前面定义的 delete_event 函数
* 传给回调函数的 data 参数值是 NULL,它会被回调函数忽略
*/
g_signal_connect( G_OBJECT( window ), "delete_event",
G_CALLBACK( delete_event ), NULL ); /**
* 连接 "destroy" 事件到一个信号处理函数,对该窗口调用
* gtk_widget_destroy 函数或在 "delete_event" 回调函数
* 中返回 FALSE 值都会触发该事件
*/
g_signal_connect( G_OBJECT( window ), "destroy",
G_CALLBACK( destroy ), NULL ); // 设置窗口边框的宽度
gtk_container_set_border_width ( GTK_CONTAINER(window), 10 );
// 创建一个标签为 Hello World 的新按钮
button = gtk_button_new_with_label( "Hello World" ); // 当按钮触发 "clicked" 事件时,会调用回调函数 hello
g_signal_connect( G_OBJECT( button ), "clicked",
G_CALLBACK( hello ), "1" ); // 当按钮触发 "clicked" 事件时,调用 gtk_widget_destroy(window)
// 来关闭窗口,"destroy" 信号会从这里或从窗口管理器发出
// g_signal_connect_swapped (G_OBJECT (button), "clicked",
// G_CALLBACK (gtk_widget_destroy),window); // 把按钮放入窗口(一个gtk容器)中
gtk_container_add ( GTK_CONTAINER( window), button ); // 显示新创建的按钮和窗口
gtk_widget_show( button );
gtk_widget_show( window ); // 程序运行停在这里等待事件的发生(如键盘事件/鼠标事件)
gtk_main(); return 0;
}

两个按钮

02_two_buttons.c

#include <gtk/gtk.h>

// 改进回调函数,传递到该函数的数据将打印到标准输出中(stdout)
void callback( GtkWidget *widget, gpointer data )
{
g_print( "%s", (gchar *) data );
} // 回调函数2
gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
gtk_main_quit();
return FALSE;
} int main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1; gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); // 设置窗口标题
gtk_window_set_title( GTK_WINDOW( window ), "Hello Buttons!" ); g_signal_connect( G_OBJECT( window ), "delete_event",
G_CALLBACK( delete_event ), NULL ); gtk_container_set_border_width( GTK_CONTAINER( window ), 20 ); // 创建一个组装盒,组装盒非可见,它仅被作为排列构件的工具
box1 = gtk_hbox_new( FALSE, 1 );
// 把组装盒放入主窗口中
gtk_container_add ( GTK_CONTAINER( window ), box1 ); button = gtk_button_new_with_label( "Hello" );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK(callback), "hello"); // 代替 gtk_container_add, 把按钮放入组装盒中, 组装盒已经放入窗口中了
gtk_box_pack_start( GTK_BOX( box1 ), button, TRUE, TRUE, 0 );
gtk_widget_show( button ); button = gtk_button_new_with_label( "World" );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK(callback), "World");
gtk_box_pack_start( GTK_BOX( box1 ), button, TRUE, TRUE, 0 );
gtk_widget_show( button ); button = gtk_button_new_with_label( "!" );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK(callback), "!");
gtk_box_pack_start( GTK_BOX( box1 ), button, TRUE, TRUE, 0 );
gtk_widget_show( button ); gtk_widget_show( box1 );
gtk_widget_show( window ); gtk_main(); return 0;
}

一图片和一按钮

03_image_and_button.c

#include "gtk/gtk.h"

int main( int argc, char *argv[] )
{
GtkWidget* window;
GtkWidget* vbox;
GtkWidget* image;
GtkWidget* button; gtk_init( &argc, &argv ); window = gtk_window_new( GTK_WINDOW_POPUP );
gtk_window_set_title( GTK_WINDOW(window), "Splash窗口" );
g_signal_connect( G_OBJECT(window), "destroy", G_CALLBACK( gtk_main_quit ), NULL ); // 设置窗口处于屏幕中央
gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_CENTER );
// gtk_container_set_border_width( GTK_CONTAINER(window), 20 ); vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add( GTK_CONTAINER(window), vbox ); image = gtk_image_new_from_file("gnome-desktop.png");
gtk_box_pack_start( GTK_BOX(vbox), image, FALSE, FALSE, 0 ); button = gtk_button_new_with_label( "Splash窗口" );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( gtk_main_quit ), NULL ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
gtk_widget_show_all( window ); gtk_main(); return FALSE;
}

可前进后退的提示窗口

04_notify_window.c

#include <gtk/gtk.h>

// XPM格式图像数据
static char * book_open_xml[] = {
"16 16 4 1",
" c None s None",
". c black",
"X c #808080",
"o c white",
" ",
" .. ",
" .Xo. ... ",
" .Xoo. ..oo. ",
" .Xooo.Xooo... ",
" .Xooo.oooo.X. ",
" .Xooo.Xooo.X. ",
" .Xooo.oooo.X. ",
" .Xooo.Xooo.X. ",
" .Xooo.oooo.X. ",
" .Xoo.Xoo..X. ",
" .Xo.o..ooX. ",
" .X..XXXXX. ",
" ..X....... ",
" .. ",
" "
}; // 自定义提示
static gchar *info[5] = {
"此软件用于测试每日提示功能的实现,如果你发现问题请及时回复。",
"我们的目的是把GTK+2.0的大多数功能奉献给每一位自由软件爱好者和开发者。",
"每一位Linux的支持者都会让我们增加一分信心,Linux最终仍是台式计算机操作系统。",
"计算机软件技术是一种科学技术,它和人类历史上其他的科学技术一样,是允许每一人自由使用的。",
"当前你测试完此程序后,请设法把它附加到你创作的软件当中去,这是你成功的第一步。"
}; static GtkWidget *window; // 主窗口
static GtkWidget *frame; // 框架
static GtkWidget *pre_button; // 上一提示按钮
static GtkWidget *next_button; // 下一提示按钮
static GtkWidget *label; // 提示信息内容标签
static GtkWidget *title; // 框架标题 gint current_info = 0; // 当前提示信息计数 // 创建框架控件标题
GtkWidget* create_title( GtkWidget *data )
{
GtkWindow *title;
GtkWindow *hbox;
GtkWindow *image;
GtkWindow *label;
GtkWindow *pixmap;
GtkWindow *mask;
GdkWindow *window; pixmap = gdk_pixbuf_new_from_xpm_data ( book_open_xml );
image = gtk_image_new_from_pixbuf( pixmap );
label = gtk_label_new( "新的标题" );
hbox = gtk_hbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX( hbox ), image, FALSE, FALSE, 2 );
gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 2 ); return hbox;
} GtkWidget* create_button( gchar* stockid, gchar* title )
{
GtkWidget *button;
GtkWidget *image;
GtkWidget *label;
GtkWidget *hbox; image = gtk_image_new_from_stock( stockid, GTK_ICON_SIZE_MENU );
label = gtk_label_new( title );
hbox = gtk_hbox_new( FALSE, 0 );
gtk_box_pack_start( GTK_BOX( hbox ), image, FALSE, FALSE, 3 );
gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 3 ); button = gtk_button_new();
gtk_container_add( GTK_CONTAINER(button), hbox ); return button;
} // 上一提示
void pre_info( GtkButton *button, gpointer data )
{
gint i;
i = current_info - 1;
if (i == -1 ) return;
if (i == 0 ) gtk_widget_set_sensitive( pre_button, FALSE );
current_info = i;
gtk_widget_set_sensitive( next_button, TRUE );
gtk_label_set_text( GTK_LABEL( label ), info[current_info] );
} // 下一提示
void next_info( GtkButton *button, gpointer data )
{
gint i;
i = current_info + 1;
if (i == 5 ) return;
if (i == 4 ) gtk_widget_set_sensitive( next_button, FALSE );
current_info = i;
gtk_widget_set_sensitive( pre_button, TRUE );
gtk_label_set_text( GTK_LABEL( label ), info[current_info] );
} int main( int argc, char* argv[] )
{
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *bbox;
GtkWidget *button;
GtkWidget *image;
GtkWidget *title; gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( gtk_main_quit ), NULL ); gtk_window_set_title( GTK_WINDOW( window ), "每日提示" );
gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_CENTER );
gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
gtk_widget_realize( window ); vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_add( GTK_CONTAINER( window ), vbox ); hbox = gtk_hbox_new( FALSE, 0 );
gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 5 ); image = gtk_image_new_from_file( "gnome-desktop.png" );
gtk_box_pack_start( GTK_BOX( hbox ), image, FALSE, FALSE, 5 ); frame = gtk_frame_new( NULL );
title = create_title( window );
gtk_frame_set_label_widget( GTK_FRAME( frame ), title );
gtk_box_pack_start( GTK_BOX( hbox ), frame, TRUE, TRUE, 5 ); label = gtk_label_new( NULL );
gtk_label_set_text( GTK_LABEL( label ), info[0] );
gtk_label_set_line_wrap( GTK_LABEL( label ), TRUE );
gtk_container_add( GTK_CONTAINER( frame ), label ); bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout( GTK_BUTTON_BOX( bbox ), GTK_BUTTONBOX_END );
gtk_box_pack_start( GTK_BOX( vbox ), bbox, FALSE, FALSE, 5 ); button = gtk_check_button_new_with_label( "每次启动时显示" );
gtk_box_pack_start( GTK_BOX( bbox ), button, FALSE, FALSE, 5 ); pre_button = create_button( GTK_STOCK_GO_BACK, "上一提示" );
gtk_widget_set_sensitive ( pre_button, FALSE );
g_signal_connect( G_OBJECT( pre_button ), "clicked", G_CALLBACK( pre_info ), NULL );
gtk_box_pack_start( GTK_BOX( bbox ), pre_button, FALSE, FALSE, 5 ); next_button = create_button( GTK_STOCK_GO_FORWARD, "下一提示" );
g_signal_connect( G_OBJECT( next_button ), "clicked", G_CALLBACK( next_info ), NULL );
gtk_box_pack_start( GTK_BOX( bbox ), next_button, FALSE, FALSE, 5 ); button = gtk_button_new_from_stock( GTK_STOCK_OK );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( gtk_main_quit ), NULL );
gtk_box_pack_start( GTK_BOX( bbox ), button, FALSE, FALSE, 5 ); gtk_widget_show_all( window );
gtk_main(); return FALSE;
}

... 后面有空继续更新

总结

gtk+ 现有资料已经很少了, 属于淘汰型技术了, 勿深究.

GTK入门的更多相关文章

  1. GTK入门学习:布局容器之固定布局

    前面我们学习的水平.垂直和表格布局容器,控件会跟着容器大小的变化进行自己主动适应.而固定布局容器里的控件则不会跟着变化( 则固定不变 ). 固定布局的创建: GtkWidget *gtk_fixed_ ...

  2. GTK入门学习:布局练习之计算器

    接下来,我们做一个布局练习.例如以下图: 我们用表格布局实现,表格布局參考坐标例如以下: 这里我们用到行编辑控件( GtkEntry ). 行编辑的创建: GtkWidget * gtk_entry_ ...

  3. GTK入门学习:布局容器之水平布局

    假设我们希望窗体里多放加入几个控件,直接加入是不成功的.由于窗体仅仅能容纳一个控件的容器. 这时候.我们须要借助布局容器,我们先把布局容器加入到窗体里.然后再把所须要加入的控件放在布局容器里. 布局容 ...

  4. GTK入门学习:glade的使用

    搭建好环境后,在终端敲 glade 就可以启动glade工具. glade的总体框图: 经常使用控件选择区:列举了经常使用的控件,经常使用的有三类:顶层(主窗体等).容器(各种布局容器等).控制和显示 ...

  5. 怎样在Windows和Linux下写相同的代码

    目前,Linux在国内受到了越来越多的业内人士和用户的青睐.相信在不久的将来,在国内为Linux开发 的应用软件将会有很大的增加(这不,金山正在招兵买马移植WPS呢).由于未来将会是Windows和L ...

  6. 用PYTHON首选的GUI库WXPYTHON做程序界面

    大家好,我是A8U神经网络,今天又要跟大家分享一下wxWidgets开发神经网络程序界面的一些经验,希望对开发有兴趣的朋友有所帮助.跨平台的GUI工具库以GTK +,Qt和wxWidgets闻名. G ...

  7. C语言基于GTK+Libvlc实现的简易视频播放器(二)

    简易视频播放器-全屏播放 一.课程说明 上一次我们使用gtk+libvlc实现了一个最简单的视频播放器,可以实现点击按钮暂定和停止播放视频,以及同步显 示视频播放进度,但即使作为一个视频播放器,只有这 ...

  8. Linux 下从头再走 GTK+-3.0 (一)

    原本由于项目需求在 Linux 下学习过一段时间的 GTK+2.0 图形开发,时隔一段时间,想真正深入学习一下 GTK . 这次直接从头学习 GTK+-3.0 ,并写下博文便于日后查看,也方便新手入门 ...

  9. Xamarin.Forms入门学习路线

    Xamarin 介绍 Xamarin是一套跨平台解决方案,目的是使用C#语言创造原生的iOS,Android,Mac和Windows应用. Xamarin的三个优势: Xamarin App拥有原生A ...

随机推荐

  1. ubuntu安装discourse论坛----结合在apache服务上建立虚拟主机

    指导操作:https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md 一.先安装 Docker / Git: wg ...

  2. django ajax发送post请求

    第一种:将csrf_token放在from表单里 <script> function add_competion_goods() { $.ajax({ url: "{% url ...

  3. 066、Java面向对象之以分步的方式实例化对象

    01.代码如下: package TIANPAN; class Book { // 定义一个新的类 String title; // 书的名字 double price; // 书的价格 public ...

  4. oracle通用帮助类

    需要的dll( EntityFramework.6.0.0Oracle.ManagedDataAccess.12.1.2400System.Configuration.dllEmitMapper.1. ...

  5. Ceph 概念理解

    简介 Ceph是一个可靠地.自动重均衡.自动恢复的分布式存储系统,根据场景划分可以将Ceph分为三大块,分别是对象存储.块设备存储和文件系统服务. 在虚拟化领域里,比较常用到的是Ceph的块设备存储, ...

  6. Dive into re Module in Python

    Dive into RE in Python Standard re module in python is powerful to handle text manipulation,such as ...

  7. Irecycleview 的初次使用简单介绍(irecycleview 下拉刷新上拉加载)

    导包 还得加一个maven地址自己也看一下作者git把有详细解释(自己也要导入recycleview的包) 我的例子下载地址  https://www.lanzous.com/i32yzaj impl ...

  8. UVA - 10562 Undraw the Trees(多叉树的dfs)

    题意:将多叉树转化为括号表示法. 分析:gets读取,dfs就好了.注意,样例中一行的最后一个字母后是没有空格的. #pragma comment(linker, "/STACK:10240 ...

  9. s5pc100开发板网卡驱动的移植

    相关软件下载地址:http://pan.baidu.com/s/16yo8Y fsc100开发板 交叉编译工具:arm-cortex_a8-linux-gnueabi-gcc 平台代码修改 vim   ...

  10. sass的安装和基础语法

    安装 下载ruby安装包[官网非常慢ruby官网] ruby-2.3.3-x64-mingw32.7z 下载sass sass-3.7.4.gem 方法一: ruby压缩包,解压即可,在bin目录下, ...