环境准备

官网下载 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. 记一次Redis+Getshell经验分享

    前言: 当我们接到一个授权渗透测试的时候,常规漏洞如注入.文件上传等尝试无果后,扫描端口可能会发现意外收获. 知己知彼乃百战不殆,Redis介绍: 简单来说 redis 就是一个Key-Value类型 ...

  2. Linux安装C++环境

    centos 安装gcc-c++ yum install gcc-c++ 安装CMake yum install cmake 切换gcc版本 安装devtoolset-x 安装devtoolset-3 ...

  3. 洛谷 P2634 聪聪可可

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

  4. 利用jQuery实现PC端href生效,移动端href失效

    今天要写一个功能,记录一下吧.if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){ $('.item-a').attr('href' ...

  5. Django(七)模型:字段属性、字段选项(参数)

    一.模型类属性命名限制 参考:https://docs.djangoproject.com/zh-hans/3.0/topics/db/models/ 1)不能是python的保留关键字. 2)不允许 ...

  6. Day 31:CSS选择器、常用CSS样式、盒子模型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. ping不通www.baidu.com,但可以访问www.baidu.com网页

    https://blog.csdn.net/stpeace/article/details/45116425 了解网络的人, 基本上都用过ping命令, 这个优秀的小工具通常能非常靠谱地检测网络的连通 ...

  8. 51nod:天堂里的游戏

    天堂里的游戏 李陶冶 (命题人) System Message (测试) 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 多年后,每当Noder看到吉普赛人,就会想起那个遥远的下午. ...

  9. 指令——df

    df是disk free 的简称,这个指令的功能和作用是查看磁盘空间. 可以加上 -h 的选项,来提高可读性. [he@localhost ~]$ df -h文件系统(磁盘名称)      总容量  ...

  10. 八十八、SAP中ALV事件之二,事件的定义和事件子例程

    一.我们来到SE37,找到REUSE_ALV_EVENTS_GET相关的定义 二.我们需要用到下面这3个事件 三.我们添加一个第五步,并把显示ALV座位第六步.在第五步中定义三个事件 四.在末尾,添加 ...