gtk_overviewGTK入门

GTK(原名)最初是GIMP的专用开发库(),后来发展为Unix-like系統下开发图形界面的应用程序的主流开发工具之一。 GTK(原名)最初是的专用开发库(),后来发展为系統下开发的应用程序的主流开发工具之一。GTK是,并且是GNU计划的一部分。自2019年2月6日起,GTK+改名为GTK。是展示GTK +版本3中許多GUI小示例的集合。 阅读详情

GTK入门

Gtk+概述

GUI

GUI 含义: (Graphics User Interface)

图形用户界面, 是计算机与使用者之间的对话接口, 是计算机重要的组成部分, 比如说咱们使用电脑或手机看到的 Windows 的桌面或 wps 软件显示的窗口界面等都是 GUI, 都是图形界面开发出来的图形界面的软件。

GUI 组成 : 桌面、 视窗、 菜单、 按钮、 图标等等

GUI 特点 :

可以使操作更加简单, 更加快捷、 更加人性化。 八十岁的老奶奶也会使用智能手机

早期的操作系统比如 DOS, 属于 CUI(Command line User Interface)

命令行模式的人机接口。

GTK+

GTK+是一套在 GIMP 的基础上发展而来的高级的、 可伸缩的现代化、 跨平台图形工具包, 它可以很方便地制作图形交互界面( GUI )。

GTK+特点:

稳定、 跨平台、 多种语言绑定、 接口丰富、 与时俱进、 算法丰富、 移动嵌入式应用广泛

https://www.gtk.org/

环境搭建

linux 下

1、安装

gtk+2.0所需的所有文件统通下载安装完毕

sudo apt-get install libgtk2.0*

2、测试

运行:

pkg-config --cflags --libs gtk+-2.0

现象:

-pthread -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/include/gtk-2.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12

说明成功

GTK+数据类型之C语言类型

  • 整数类型:gint8、guint8、gint16、guint16、gint32、guint32、gint64、guint64。不是所有的平台都提供64位整型
  • 整数类型 gshort、glong、gint 和 short、long、int 相同
  • 布尔类型 gboolean :gboolean 可以取两个值:TRUE 和 FALSE
  • 字符型 gchar 和 char 相同
  • 浮点型 gfloat 和 gdouble 和 float、double 完全等价
  • 指针 gpointer 对应于标准C的 void *
  • const gpointer 对于于标准C的 const void *

GTK+的面向对象机制

面向对象编程语言(如C++、Java)把 数据 和 对数据的操作封装在一起构成类,由 类来 产生对象,由对象来构建程序。类中对数据的操作由函数来完成,这种函数被称为成员函数或方法。

面向对象语言通过继承、重载、多态等机制大大增强软件的可重用性和可维护性。C语言虽然不是面向对象语言,但GTK+以及建立在其上的GNOME库却使C语言模拟出了一些典型的面向对象机制,如封装、继承和多态。

对象的一个主要特性是将数据和对数据的操作封装在一起,受保护的私有数据只能通过成员函数才能访问和修改。GTK+使用C语言的结构体来模拟对象,虽然有些缺陷但基本模拟出了对象的基本特征。

有了对象作为基础,通过在对象中加入新的数据和对这些数据进行操作的函数,就实现了继承。被 继承的类(类相当于一种自定义数据类型,由类来定义对象)称为父类或基类,由基础类派生出来的类称为子类或派生类。子类继承了父类的数据和对这些数据进行 操作的成员函数,并加入了新的数据和成员函数,实现了对原有父类的重用和扩展,从而实现了可重用性和可扩展性。

GTK+中有一个类,它是所有其他类的父类,这个类是GtkObject。GTK+中最常用的按钮控件也是一个类,它继承自GtkObject。它与GtkObject的继承关系是:

GtkObject ->GtkWidget ->GtkContainer ->GtkBin ->GtkButton

对象(类)是由结构体模拟的,每一个子类所在的结构体都包含了父类的结构体,子类结构体的第一个成员是其父类结构体,示例代码如下:

struct GtkObject 
{
    //...
};

struct GtkWidget 
{
    GtkObject object;
    //..
};

struct GtkContainer 
{
    GtkWidget widget;
    //...
};

struct GtkBin 
{
    GtkContainer container;
    //...
};

每个子类都包含了其父类的所有数据,并且父类的数据位于子类结构体的开始。对于一个GtkButton 类型的 button 控件变量(它其实是一个指向GtkButton 结构体的指针),通过宏 GTKBIN(button) 就得到了其父类(GTK+预定义的 宏GTKBIN其实是进行了强制类型转换,把一个 GtkButton 类型的指针强制转化为 GtkBin 类型的指针)

test.c 测试程序 :

#include<stdio.h>
#include<stdlib.h>

#define FATHER(child) (struct Father *)(child)

void print1(int i)
{
    printf("this is father and i = %d\n", i);
}

void print2(int i)
{
    printf("this is child  and i = %d\n", i);
}

// 模拟父类 
struct Father 
{
   // 成员变量 
    int a;
   // 成员函数, 指向函数的指针
    void (*pointer1_to_function)(int);
};

// 模拟子类
struct Child 
{
   // 模拟继承 , 结构体 Father
    struct Father f;
    int b;
    void (* pointer2_to_function)(int);
};

void father_member_funtion(struct Father *f, char *string)
{
    printf("\n");

     f->pointer1_to_function(f->a);

    printf("%s\n\n", string);
}

int main()
{
    // 定义指向结构体 Child 的指针
    struct Child *p_child;
    p_child = (struct Child *)malloc(sizeof(struct Child));

    // 成员初始化
    p_child->f.a = 10;
    p_child->f.pointer1_to_function = print1;

    p_child->b = 20;
    p_child->pointer2_to_function = print2;

    // 调用成员函数
    p_child->pointer2_to_function(p_child->b);

    // 将指针p_child强制转换为指 向Father结构体的指针
    struct Father *p_father = FATHER(p_child);

    p_father->pointer1_to_function(p_father->a);

    // 实现方法, 避免了在结构体Father中保存函数指针
    father_member_funtion(p_father, "hello");

    return 0;
}

GTK+定义了很多生成对象 或 对对象进行操作的函数

// 创建了一个对象
GtkWidget *button;

button = gtk_button_new_with_label("label");

所有创建对象的函数在其名称上都有“ new ”这个词。

// 创建了一个显示文本的按钮
gtk_button_new_with_label

可以当作父类来对待所有子类(多态),按钮 button 的真正类型是 GtkButton,却也可以作为一个指向 GtkWidget 类型的指针。

当调用一个函数对一个对象进行相关操作时,该对象的地址作为第一个参数传给函数。

//显示按钮的函数
gtk_widget_show(button);

button 是一个指向 GtkWidget 结构体的指针,它也表示一个按钮控件。

面向对象语言中子类可以调用父类的函数,在 GTK+ 中只要使用一些宏将子类强制转换为父类即可。

gtk_container_add(GTK_CONTAINER(window), button);

gtk_container_add 函数是类 GtkContainer 的一个函数,而 window 代表一个窗口,它是 GtkWindow 类型的指针。

GtkWindow 是 GtkContainer 的子类,也就是 GtkWindow 继承自 GtkContainer,当然它们都是从 GtkObject 派生出来的,GtkObject 是它们的祖先:

GtkObject -> GtkWidget -> GtkContainer -> GtkBin -> GtkWindow

空白窗口

栗子 : first_window.c

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    // 初始化,必须在控件定义之前使用
    gtk_init(&argc, &argv&);

    /* 创建窗口(参数有两种形式)
     * GTK_WINDOW_TOPLEVEL:顶层窗口,包含窗口的标题栏和边框,有最大化最小化
     * GTK_WINDOW_POPUP:弹出窗口, 没有窗口的标题栏和边框,不能改变大小和移动
     */
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    // 显示窗口控件
    gtk_widget_show(window);    

    // 主事件循环,程序也必须要这个    
    gtk_main();

    return 0;
}

Makefile

CC = gcc
MAINC = first_window.c
EXEC = first_window

CFLAGS = `pkg-config --cflags --libs gtk+-2.0`

main:
    $(CC) $(MAINC) -o $(EXEC) $(CFLAGS)

clean:
    rm $(EXEC) -rf

GTK 程序的基本框架 :

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    // 初始化,必须在控件定义之前使用
    gtk_init(&argc, &argv&);

    //代码

    // 主事件循环,程序也必须要这个    
    gtk_main();

    return 0;
}

GtkWidget 是 GTK+控件类型, GtkWidget * 能指向任何控件的指针类型。

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

创建一个窗口并返回这个窗口的控件指针

gtk_window_new()

窗口的创建 :

/*
GtkWindowType 是一个枚举, 有两种情况:
GTK_WINDOW_TOPLEVEL: 有边框
GTK_WINDOW_POPUP: 没边框
*/
GtkWidget *gtk_window_new(GtkWindowType type);

标题的设置 :

void gtk_window_set_title(GtkWindow *window, const gchar *title);

窗口最小大小的设置

void gtk_widget_set_size_request(GtkWidget *widget,gint width,gint height);

窗口伸缩设置( FALSE 为不可伸缩 )

void gtk_window_set_resizable(GtkWindow *window, gboolean resizable);

显示或隐藏所有控件 :

void gtk_widget_show_all(GtkWidget *widget);

void gtk_widget_hide_all(GtkWidget *widget);

窗口在显示器位置的设置

/*
position 常用有 4 种情况:
GTK_WIN_POS_NONE: 不固定
GTK_WIN_POS_CENTER: 居中
GTK_WIN_POS_MOUSE: 出现在鼠标位置
GTK_WIN_POS_CENTER_ALWAYS: 窗口总是居中
*/
void gtk_window_set_position(GtkWindow *window, GtkWindowPosition position);

栗子 : Window.c

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    //初始化
    gtk_init(&argc, &argv);

    //创建顶部窗口
    GtkWidget *Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    //设置窗口标题
    gtk_window_set_title(GTK_WINDOW(Window), "cpucode Window");

    /* 
    GTK_WIN_POS_NONE: 不固定
    GTK_WIN_POS_CENTER: 居中
    GTK_WIN_POS_MOUSE: 出现在鼠标位置
    GTK_WIN_POS_CENTER_ALWAYS: 窗口总是居中 
    */
    gtk_window_set_position(GTK_WINDOW(Window), GTK_WIN_POS_CENTER);

    //设置窗口大小
    gtk_widget_set_size_request(Window, 400, 300);

    //设置窗口固定
    gtk_window_set_resizable(GTK_WINDOW(Window), FALSE);

    //"destroy" 和 gtk_main_quit 连接
    g_signal_connect(Window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    // 显示窗口全部控件
    gtk_widget_show_all(Window);
    //gtk_widget_hide_all(window);    // 隐藏窗口

    //主事件循环
    gtk_main();

    return 0;
}

带按钮的窗口

控件的介绍 :

控件是对数据和方法的封装。 控件有自己的属性和方法。 属性是指控件的特征。 方法是指控件的一些简单而可见的功能。

控件的分类: 容器控件, 非容器控件。

容器控件: 它可以容纳别的控件。 容器控件分为两类, 一类只能容纳一个控件, 如窗口, 按钮; 另一类能容纳多个控件, 如布局控件。

非容器控件: 它不可以容纳别的控件, 如标签、 行编辑。

// 创建一个带内容的按钮
GtkWidget *gtk_button_new_with_label(const gchar *label );
//获得按钮上面的文本内容
const gchar *gtk_button_get_label(GtkButton *button );
// 把控件添加到窗口容器里
// container: 容纳控件的容器
// widget: 要添加的控件
void gtk_container_add(GtkContainer *container, GtkWidget *widget);

栗子 : window_with_button.c

#include <gtk/gtk.h> // 头文件

int main( int argc,char *argv[] )
{
    gtk_init(&argc, &argv); // 初始化

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建顶层窗口

    // 设置窗口边框的宽度(窗口里的控件与窗口边框间隔为 15)
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);

    // 创建按钮, 文本信息
    GtkWidget *button = gtk_button_new_with_label("cpuocde");
    const char *str = gtk_button_get_label( GTK_BUTTON(button) ); // 获得按钮的内容

    printf("str = %s\n", str);

    // 把按钮放入窗口(窗口也是一种容器)
     gtk_container_add(GTK_CONTAINER(window), button);

    // 显示控件有两种方法: 逐个显示, 全部显示
    // gtk_widget_show(button);
    // gtk_widget_show(window);

    gtk_widget_show_all(window); // 显示窗口全部控件

    gtk_main(); // 主事件循环
    return 0;
}

信号与回调函数机制

GTK+采用了信号与回调函数来处理窗口外部传来的事件、 消息或信号。 当信号发生时, 程序自动调用为信号连接的回调函数。

窗口关闭时触发的常用信号: destroy , delete-event

操作按钮触发的常用信号: clicked, pressed, released

/*
 * 信号与回调函数的连接
 * instance: 信号的发出者
 * detailed_signal: 要连接信号的名称
 * c_handler: 回调函数的名称, 需要用 G_CALLBACK()进行转换
 * data: 传递给回调函数的参数
 */
gulong g_signal_connect(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data );

回调函数的定义

//信号连接函数
g_signal_connect(button, "pressed", G_CALLBACK(callback), NULL);
// 回调函数
// button: 信号的发出者
// user_data: 传给回调函数的数据
void callback( GtkButton *button, gpointer user_data );

栗子 : signal.c

#include <gtk/gtk.h>    // 头文件

// 按钮按下的处理函数, gpointer 相当于 void *
void deal_pressed(GtkButton *button, gpointer user_data)
{
    // 获得按钮的文本信息
    const gchar *text = gtk_button_get_label( button );

    // g_print() 相当于C语言的 printf(), gchar相当于char
    g_print("button_text = %s; user_data = %s\n", text, (gchar *)user_data);
}

int main( int argc,char *argv[] )
{
    gtk_init(&argc, &argv);        // 初始化

    // 创建顶层窗口
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 

    // 设置窗口边框的宽度(窗口里的控件与窗口边框间隔为15)
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);

    /* 当窗口关闭时,窗口会触发destroy信号,
     * 自动调用gtk_main_quit()结束程序运行。
     */
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    //创建按钮
    GtkWidget *button = gtk_button_new_with_label("cpucode");

    // 把按钮放入窗口(窗口也是一种容器)
    gtk_container_add(GTK_CONTAINER(window), button);    

    /* 按钮按下(pressed)后会自动调用 deal_pressed()
     * "is pressed"是传给deal_pressed()的数据
     */
    g_signal_connect(button, "pressed", G_CALLBACK(deal_pressed), "is pressed");

    gtk_widget_show_all(window);    // 显示窗口全部控件

    gtk_main();        // 主事件循环

    return 0;
}

常用布局

设定控件在整个窗口中的位置和尺寸

常用的布局方式

  • 水平布局 GtkHBox
  • 垂直布局 GtkVBox
  • 表格布局 GtkTable
  • 固定布局 GtkFixed
水平布局
// 创建水平布局容器
// homogeneous: 容器内控件是否均衡排放(大小一致)
// spacing: 控件之间的间隔
GtkWidget *gtk_hbox_new(gboolean homogeneous, gint spacing);
// 添加控件到布局容器中
gtk_container_add(GtkContainer *container, GtkWidget *widget );

栗子 : hbox.c 横向布局

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    //创建窗口
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    //设置标题
    gtk_window_set_title(GTK_WINDOW(window), "cpucode layout");

    //设置窗口边框的宽度
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    /*
     * 创建横向盒状容器
     * GtkWidget *gtk_vbox_new(gboolean homogeneous, gint spacing);
     * homogeneous:容器内控件是否均衡排放(TRUE or FALSE)
     * spacing: 控件之间的间隔
     */
    GtkWidget *hbox = gkt_hbox_new(TRUE, 10);

    //把横向容器放到窗口
    gtk_container_add(GTK_CONTAINER(window), hbox);
    //button1
    GtkWidget *button = gtk_button_new_with_label("button1");
    // 按钮添加到布局容器里
    gtk_container_add(GTK_CONTAINER(hbox), button);

    // button2
    button = gtk_button_new_with_label("button2");
    // 按钮添加到布局容器里
    gtk_container_add(GTK_CONTAINER(hbox), button);

    // button3
    button = gtk_button_new_with_label("button3");
    gtk_container_add(GTK_CONTAINER(hbox), button);     // 按钮添加到布局容器里

    gtk_widget_show_all(window);    // 显示窗口控件

    gtk_main();     // 主事件循环

    return 0; 
}

垂直布局

垂直布局容器的操作和水平布局的操作几乎是一样

//创建垂直布局容器
gtk_vbox_new()
//标签的创建
GtkWidget *gtk_label_new(const gchar *str);
// 设置标签的内容
void gtk_label_set_text(GtkLabel *label, const gchar *str);
//获得标签的内容
const gchar *gtk_label_get_label(GtkLabel *label );

栗子 : vbox.c 纵向布局

#include <gtk/gtk.h>    // 头文件

/*
 * 设置label字体的大小
 * label: 需要操作的label
 * size:  字体的大小
 */
void set_label_font_size(GtkWidget *label, int size)
{
    // 字体指针
    PangoFontDescription *font;

    //参数为字体名字
    font = pango_font_description_from_string("cpucode");

    // #define PANGO_SCALE 1024
    // 设置字体大小   
    pango_font_description_set_size(font, size * PANGO_SCALE);
    // 改变label的字体大小
    gtk_widget_modify_font(label, font);
    // 释放字体指针分配的空间
    pango_font_description_free(font);
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);   // 初始化

    // 创建窗口
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    // 设置标题 
    gtk_window_set_title(GTK_WINDOW(window), "cpucode vertical layout");

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
     // 设置窗口边框的宽度
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);
    // 创建纵向盒状容器
    GtkWidget *vbox = gtk_vbox_new(TRUE, 15);
    // 把纵向盒状容器放入窗口
    gtk_container_add(GTK_CONTAINER(window), vbox);

    //label one
    // 创建标签
    GtkWidget *label = gtk_label_new("label one");
    // 设置label字体大小,这个为自定义的函数
    set_label_font_size(label, 30);
    // 将按钮放在布局容器里
    gtk_container_add(GTK_CONTAINER(vbox), label);

    // label two
    label = gtk_label_new("text");

    gtk_label_set_text(GTK_LABEL(label), "label two");          // 设置label的内容
    const char *str = gtk_label_get_label( GTK_LABEL(label) ); // 获得标签的内容
    g_print("str = %s\n", str);

    // 设置label字体大小,这个为自定义的函数
    set_label_font_size(label, 30);
    gtk_container_add(GTK_CONTAINER(vbox), label);         // 将按钮放在布局容器里

    // label three
    label = gtk_label_new("label three");
    set_label_font_size(label, 30);    // 设置label字体大小,这个为自定义的函数
    gtk_container_add(GTK_CONTAINER(vbox), label);         // 将按钮放在布局容器里

    gtk_widget_show_all(window);    // 显示窗口控件

    // 主事件循环
    gtk_main();

    return 0;
}

Makefile

CC = gcc  
MAINC = vbox.c
EXEC = vbox

CFLAGS = `pkg-config --cflags --libs gtk+-2.0`

main:  
    $(CC) $(MAINC) -o $(EXEC) $(CFLAGS)
clean:
    rm $(EXEC) -rf

表格布局
// 创建表格布局容器
// rows:行数
// coumns:列数
// homogeneous: 容器内表格的大小是否一致
GtkWidget*gtk_table_new(guint rows, guint columns, gboolean homogeneous );
// 添加控件到布局容器中
// table: 要容纳控件的容器
// widget: 被容纳控件
// 后四个参数 : 控件摆放的坐标
void gtk_table_attach_defaults(GtkTable *table, GtkWidget *widget, 
                     guint left_attach, guint right_attach,
                     guint top_attach, guint bottom_attach );

image-20200806132252551

栗子 : table.c 表格布局

#include <gtk/gtk.h>    // 头文件

// button 1, button 2处理函数
void callback(GtkButton *button, gpointer data)
{
    g_print("%s is clicked!\n", (gchar *)data);
}

// close button处理函数
void close_window(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit();
}

int main(int argc, char *argv[]) 
{
    gtk_init(&argc, &argv);     // 初始化
    // 创建窗口
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    // 设置标题 
    gtk_window_set_title(GTK_WINDOW(window), "cpucode table");

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    // 设置窗口边框的宽度
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);

    /*
     * 创建表格布局容器
     * GtkWidget * gtk_table_new(guint rows, guint columns, gboolean homogeneous);
     * rows:         行数
     * coumns:       列数
     * homogeneous: 容器内控件是否均衡排放(TRUE or FALSE)
     */
    GtkWidget *table = gtk_table_new(2, 2, TRUE);
    gtk_container_add(GTK_CONTAINER(window), table); // 容器加入窗口

    // button 1
    GtkWidget *button = gtk_button_new_with_label("buttton 1");
    g_signal_connect(button, "pressed", G_CALLBACK(callback), "button 1");
    gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 0, 1);// 把按钮加入布局

    // button 2
    button = gtk_button_new_with_label("button 2");
    g_signal_connect(button, "pressed", G_CALLBACK(callback), "button 2");
    gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 0, 1);

    // close button
    button = gtk_button_new_with_label("close");
    g_signal_connect(button, "pressed", G_CALLBACK(close_window), NULL);
    gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 2, 1, 2);

    gtk_widget_show_all(window);    // 显示窗口控件

    gtk_main();     // 主事件循环

    return 0;
}

Makefile

CC = gcc
MAINC = table.c
EXEC = table

CFLAGS = `pkg-config --cflags --libs gtk+-2.0`

main:
    $(CC) $(MAINC) -o $(EXEC) $(CFLAGS)
clean:
    rm $(EXEC) -rf

固定布局
//创建固定布局容器
GtkWidget *gtk_fixed_new(void);
// 添加控件到容器中
// fixed: 要容纳控件的容器
// widget: 被容纳控件
// x, y: 控件摆放位置的起点坐标
void gtk_fixed_put( GtkFixed *fixed, GtkWidget *widget, gint x, gint y );

栗子 : fixed.c 固定布局

#include <gtk/gtk.h> 

int main( int argc, char *argv[]) 
{
    gtk_init(&argc, &argv);     // 初始化

    GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);      // 创建窗口 
    gtk_window_set_title(GTK_WINDOW(window), "cpucode"); // 设置标题

    // 为窗口的 "destroy" 事件设置一个信号处理函数  
    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

    GtkWidget *fixed = gtk_fixed_new();     //创建一个固定容器
    gtk_container_add(GTK_CONTAINER (window), fixed); // 固定放进窗口

    GtkWidget *button; 
    int i; 

    for(i = 1 ; i <= 3 ; i++)
    {
        button = gtk_button_new_with_label ("Press me");  // 创建按钮
        // 将按钮组装到一个固定容器的窗口中
        gtk_fixed_put(GTK_FIXED(fixed), button, i * 50, i * 50); 
    }

    gtk_widget_show_all(window);  // 显示所有控件

    gtk_main();  //进入事件循环 

    return 0; 
}

Makefile

CC = gcc
MAINC = fixed.c
EXEC = fixed

CFLAGS = `pkg-config --cflags --libs gtk+-2.0`

main:
    $(CC) $(MAINC) -o $(EXEC) $(CFLAGS)
clead:
    rm $(EXEC) -rf

行编辑

//行编辑的创建
GtkWidget *gtk_entry_new(void);
//显示模式(FALSE 为密码模式)
void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible );
// 获得文本内容
const gchar *gtk_entry_get_text(GtkEntry *entry );
//设置行编辑的内容
void gtk_entry_set_text(GtkEntry *entry, const gchar *text);
//常用信号:按回车键触发
activate

栗子 : entry.c 行编辑

#include <gtk/gtk.h> 

// 按Enter,获取行编辑的内容
void enter_callback( GtkWidget *widget, gpointer entry ) 
{ 
    const gchar *entry_text; 

    // 获得文本内容
    entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); 
    printf("Entry contents: %s\n", entry_text); 
}

int main( int argc, char *argv[] )
{
    gtk_init (&argc, &argv);     // 初始化

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);     // 创建窗口
    gtk_window_set_title(GTK_WINDOW(window), "cpucode Entry");         // 设置标题
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *vbox = gtk_vbox_new(TRUE, 5);     // 垂直布局,控件均衡摆放,控件间距为0
    gtk_container_add(GTK_CONTAINER(window), vbox);     // 容器放入窗口

    GtkWidget *entry = gtk_entry_new();  // 创建行编辑     
    gtk_container_add(GTK_CONTAINER(vbox), entry);     // 加入垂直布局里
    gtk_entry_set_max_length(GTK_ENTRY(entry), 100);     // 设置行编辑显示最大字符的长度
    gtk_entry_set_text(GTK_ENTRY(entry), "hello word");  // 设置内容
    gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);      // 密码模式

    /* 如果我们想在用户输入文本时进行响应,可以为 activate 设置回调函数。
     * 当用户在文本输入构件内部按回车键时引发Activate信号;
     */
    g_signal_connect(entry, "activate", G_CALLBACK(enter_callback), entry);

    GtkWidget *hbox = gtk_hbox_new(TRUE, 0);       // 水平布局容器
    gtk_container_add(GTK_CONTAINER(vbox), hbox); // 水平布局容器加入垂直布局容器里

    // "button 1"
    GtkWidget *button1 = gtk_button_new_with_label("button 1");
    gtk_container_add(GTK_CONTAINER(hbox), button1); // 按钮1添加到水平布局容器里

    // "button 2"
    GtkWidget *button2 = gtk_button_new_with_label("button 2"); 
    gtk_container_add(GTK_CONTAINER(hbox), button2); // 按钮2添加到水平布局容器里

    // close button
    GtkWidget *button_close = gtk_button_new_with_label("close"); 
    g_signal_connect(button_close, "clicked", G_CALLBACK (gtk_main_quit), NULL); 
    gtk_container_add(GTK_CONTAINER(vbox), button_close); // 关闭按钮添加到垂直布局容器里

    gtk_widget_show_all(window); // 显示窗口所有控件

    gtk_main();         // 主事件循环

    return 0;
}

Makefile

CC = gcc
MAINC = entry.c
EXEC = entry

CFLAGS = `pkg-config -cflags --libs gtk+-2.0`

main:
    $(CC) $(MAINC) -o $(EXEC) $(CFLAGS)
clean:
    rm $(EXEC) -rf

C语言中的图形用户界面开发:使用库如GTK+或ncurses创建GUI应用程序(一) C语言开发者可以充分利用GTK+的强大功能,开发出界面美观、功能丰富、具有良好用户体验的跨平台GUI应用程序。 阅读详情

相关推荐

GTK+笔记之入门(一)

1. GTK概念 GTK+是一种跨平台的图形工具包,它可以很方便的制作图形交互界面(GUI)。 2. Linux安装

鸿墨轩 1773

GTK+:GTK+的简介、安装、使用方法之详细攻略

​ GTK+:GTK+的简介、安装、使用方法之详细攻略 目录 GTK+的简介 GTK+的安装 GTK+的使用方法 GTK+的简介 GTK+(GIMP Toolkit)是一套源码以LGPL许可协议分发、跨平台的图形工具包。最初是为GIMP写的,已成为一个功能强大、设计灵活的一个通用图形库,是GNU/Linux下开发图形界面的应用程序的主流开发工具之一。并且,GTK+也有Windows版本和Mac OS X版。 GTK+ 是一种图形用户界面(GUI)工

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 6万+

全面深入的GTK+开发工具套件指南

在GTK+中,开发者也可以创建自己的信号。创建信号通常涉及定义信号名称、默认处理程序等。一个简单的示例为创建一个按钮点击信号:/* 信号连接示例 *//* 自定义信号创建示例 */FALSE,在创建自定义信号的代码中,class_init函数用于初始化类属性,其中函数用于安装一个布尔型的样式属性,该属性可以作为自定义信号的一种表现形式。颜色方案为应用程序提供了视觉层次感和吸引力。GTK+允许开发者通过CSS来定义和应用颜色方案,包括主题色和系统颜色。

weixin_30476025的博客 1315

gtk学习总结:GTK从入门到放弃,三天包教包会

今天花了一些时间复习之前学习过的gtk,感觉东西光学不用忘得好快啊,在这做个之前学过的内容的备份,希望对大家有用,也希望大家不要从入门到放弃。文中有些代码例子可能来自《GTK从入门到精通》吧,我不记得了,或者叫《GTK中文教程》,忘记了,总之,这是一个学习笔记,希望不触及任何人的利益,起到共享学习之用。 目录 编译方法 编译脚本 01.一个简单的按钮 02.两个按钮 03.vbox:一...

RToax 4万+

分布式存储系统关于GDPR条例中的数据清除原则

文章目录前言HDFS存储系统数据的完全删除基于加解密的输入输出流的数据保护方案 前言 关于GDPR是什么,可能许多同学之前并不太了解,至少笔者在之前也是不清楚的。GDPR全称为通用数据保护条例,General Data Protection Regulation。它是一项来自欧盟的关于计算机数据保护相关的条约,旨在规范系统如何收集,管控用户私人数据的种种行为。但是当前的一些存储系统并没有完全符合...

走在前往架构师的路上 3624

Xilinx的DDR4 IP

Xilinx的DDR4 IP

weixin_39896700的博客 4458

GTK+(GIMP Toolkit)介绍

GTK+(GIMP Toolkit)是一种开源的跨平台图形用户界面(GUI)工具包,最初作为GNU图像处理程序(GIMP)的工具包而开发。它提供了一套丰富的组件和工具,使开发者能够创建直观且功能强大的应用程序界面。本文将介绍GTK+的特点、优势以及它在应用程序开发中的应用。GTK+(GIMP Toolkit)是一种开源的跨平台图形用户界面(GUI)工具包,可以用于游戏开发。虽然GTK+主要是为桌面应用程序设计的,但也可以用于构建简单的2D游戏。下面将介绍GTK+游戏开发的基本过程。

牛肉胡辣汤 1409

大红球预警版-精选+自定义板块监控

这是一款简单易用的股票大单资金监控插件,兼容通达信软件,可嵌入分时图或定制版面。它以红绿圆球直观显示主力买卖情况(红球为买,绿球为卖),支持300万以上大单语音播报。插件提供实时资金流向分析、多股同时监控、自定义预警条件等功能,无需L2账号。用户可自由切换图形/列表模式,监控特定板块,并配合幻影软件实现自动交易。虽然上涨股通常红球占优,但需结合其他指标综合判断。该插件完全免费,包含详细视频教程,适合新手使用。

guleba的博客 1794

GTK+系列---关于GTK+

什么是GTK+? GTK+或GIMP工具包是用于创建图形用户界面的多平台工具包。GTK+提供了一套完整的构件(widget),适用于从小型一次性工具到完整的应用程序套件等项目。GTK+是跨平台的,并且拥有易于使用的API,从而加快了您的开发时间。GTK+是用C语言编写的,但它是从底层设计的,支持各种各样的语言,而不仅仅是C/C++。使用来自Perl和Python等语言(尤其是与Glade GUI...

drsonxu的博客 2312

神经网络:初学者指南(专业版)

神经网络是一种受生物大脑启发的计算模型,由多层互连的人工神经元组成。本文从生物神经元结构出发,介绍了感知器模型、激活函数、网络架构(输入/隐藏/输出层)等基础概念,并详细阐述了前向传播、反向传播、损失函数和优化器等核心训练机制。同时涵盖了CNN、RNN等常见架构,以及过拟合、梯度消失等关键挑战,最后概述了神经网络在计算机视觉、NLP等领域的广泛应用。全文系统性地梳理了神经网络的基础理论和实践要点,为初学者提供了清晰的学习路径。

weixin_42107409的博客 1783

Claude code-review 插件深度解析:AI 驱动的智能代码审查系统

Claude Code Review 插件深度解析:AI 驱动的智能代码审查系统 该插件通过多 Agent 并行工作方式自动审查 PR,采用置信度评分机制(80+分保留)过滤误报,确保高质量反馈。核心功能包括: 5个专业化 Agent 并行审查(规范合规性、bug检测、历史分析等) 8步工作流程:从资格检查到 GitHub 评论发布 创新性置信度评分系统(0-100分),严格过滤7类误报 结合 CLAUDE.md 规范和历史 PR 评论实现一致性审查 技术亮点: 多 Agent 架构(Haiku/Sonne

虚心若愚 2264

GTK入门教程

GTK(GIMP Toolkit)是一套源码以LGPL许可协议分发、跨平台的图形工具包。最初是为GIMP写的,已成为一个功能强大、设计灵活的一个通用图形库,是GNU/Linux下开发图形界面的应用程序的主流开发工具之一。当然,GTK也是支持跨平台的,支持Unix类的系统、Windows,甚至手机平台。

weixin_44453694的博客 9851

基于simulink的电动汽车电机驱动系统IGBT开路故障检测

本文介绍了基于Simulink的电动汽车电机驱动系统IGBT开路故障检测方法。通过搭建永磁同步电机(PMSM)驱动系统模型,实现IGBT开路故障注入,并设计基于电流平均值与PWM逻辑比较的故障检测算法。系统可实时采集三相电流信号,通过MATLAB Function模块实现故障诊断,当检测到PWM信号与电流不匹配时输出故障报警。仿真结果显示,系统能在2.05秒内准确识别A相上管开路故障,并通过Scope和XYGraph直观展示故障特征。该方法为电动汽车电力电子系统故障诊断与容错控制提供了实用解决方案,后续可扩

xiaoheshang_123的博客 149

GTK+基本操作加图形化计算器实现

1.GTK+简介 Linux下大多数的开发都是基于字符界面的,但是在Linux下也可以开发出美观大方的图形界面,其中较为常用的是Qt和GTK+; 为什么我们要在这里说GTK+呢? 因为GTK+使用C语言作为开发语言,GTK+是开放源代码而且免费的,简单易用,执行效率高,Linux的桌面环境GNOME就是建立在GTK+的基础上; 2.GTK+的简单操作 2.1.Deeping安装GTK+ sudo ...

qq_44049351的博客 1362

Vue2 - 实现全景图Vr 720°全景效果查看预览功能,3D全景图流畅不卡顿渲染+手势拖拽+悬浮工具按钮,vue实现vr看720度全景效果方案讲解及示例代码(兼容电脑PC网页+手机H5移动端页面)

vue全景VR图,vue h5实现全景720预览,vue加载720全景图_vue怎么加载vr图片,vue实现vr全景看房,vue2实现全景效果,加载很慢卡怎么办,实现全景预览的插件,vue显示720度全景图,720°全景图显示,在h5中展示720°全景图,浏览全景图,基于vue实现vr全景预览,加载全景图,vue全景预览pannellum插件,vue实现3D全景图,实现720°全景图展示,在VUE 中使用three.js实现全景视频播放,vue项目中使用photo-sphere-viewer实现vr720度

🏆 前端领域优质创作者 3317

lvgl 9虚拟键盘控件 (lv_keyboard) 使用指南

是 LittlevGL 提供的一个虚拟键盘控件,适用于在图形界面中输入文本。与按钮矩阵类似,虚拟键盘预定义了多个键位布局,支持多种模式和自定义键位映射,能够满足各种文本输入需求。通过与文本区域 (Text Area) 的结合,键盘能够自动将输入的字符传送到指定区域。控件是 LittlevGL 提供的强大虚拟键盘解决方案,适用于任何需要文本输入的界面。通过预定义的键盘模式、自定义键位映射和文本区域自动填充功能,可以大大提升用户输入体验。无论是在嵌入式系统的用户界面中,还是在其他需要虚拟键盘的应用中,

m0_62599305的博客 2185

GTK+入门教程

GTK+入门教程(一)1. 显示一个窗口#include &lt;gtk/gtk.h&gt; int main(int argc, char *argv[]) { GtkWidget *window; gtk_init(&amp;argc, &amp;argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk...

ygyoe的专栏 2万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

工控软件开发框架,GTK和QT好难选,快来拯救开发者。

工控软件开发框架如何选,有人喜欢GTK,有人钟意QT,而且每个人都有自己的一番道理,好像说的还都有理,这种情况该怎么办呢?大千UI工场带着你深入了解下。

贝格前端工场的博客 3497

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Gtk+概述 Linux环境 按钮 窗口 布局 信号 回调函数 行编辑

Gtk+概述 GUI GUI 含义: (Graphics User Interface) 图形用户界面, 是计算机与使用者之间的对话接口, 是计算机重要的组成部分, 比如说咱们使用电脑或手机看到的 Windows 的桌面或 wps 软件显示的窗口界面等都是 GUI, 都是图形界面开发出来的图形界面的软件。 GUI 组成 : 桌面、 视窗、 菜单、 按钮、 图标等等 GUI 特点 : 可以使操作更加简单, 更加快捷、 更加人性化。 八十岁的老奶奶也会使用智能手机 早期的操作系统比如 DOS, 属于...

记录点点滴滴 1542

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【GTK+-编程指南*】

GTK+-编程指南■■■■■ ■ ■ ■ ■ ■

sinat_23896491的博客 915

GTK+ 简介

GTK

qq_33172851的博客 415

0018__GTK+:GTK+的简介、安装、使用方法之详细攻略

GTK+:GTK+的简介、安装、使用方法之详细攻略-优快云博客

行潇 503

GTK+简介

GTK+ 是一套在 GIMP 的基础上发展而来的高级的、可伸缩的现代化、跨平台图形工具包,提供一整套完备的图形构件,适用于大大小小各种软件工程项目,不论是小到只需要一个窗口,还是复杂得如桌面环境。简单来说,GTK+ 是一种函数库是用来帮助制作图形交互界面的。 GTK+ 整个函数库都是由C 语言来编写的。这对 C 爱好者来说是极大的诱惑!你也无需担心因为是 C 写的而担心好用不好用,一旦你熟悉了这

秋叶原 && Mike || 麦克 1万+

GTK+ 中的第一个程序

gtk_window_new()函数创建一个新的GtkWindow,这是一个可以包含其他窗口小部件的顶层窗口。我们在屏幕上居中放置一个窗口,在标题栏中显示一个图标,显示一个小的工具提示,并为按钮小部件创建一个助记符。当我们处理多个窗口小部件时,在容器上调用gtk_widget_show_all()比单独显示所有窗口小部件容易。gtk_window_set_icon()显示窗口的图标。将GTK_WIN_POS_CENTER常量传递给gtk_window_set_position()函数,使程序在屏幕上居中。

qq_33172851的博客 426

C语言中的图形用户界面开发:使用库如GTK+或ncurses创建GUI应用程序(三)

GTK+主要用于开发桌面应用程序,尤其是在Linux环境中,与GNOME桌面环境紧密关联。尽管GTK+最初是为Linux/GNOME设计,但经过长期发展,它已经具备良好的跨平台能力,支持Windows、macOS等主流桌面操作系统。

weixin_56154577的博客 2774

来吧,对桌面端开发框架GTK来个全景扫描,看看起独特魅力是啥。

GTK 具有强大的自定义能力,可以满足不同开发者的特殊需求。开发者可以通过多种方式进行自定义。首先,GTK 提供了丰富的主题和样式设置选项,开发者可以根据自己的需求定制应用程序的外观。例如,开发者可以选择不同的主题颜色、字体大小和样式等,使应用程序具有独特的外观。其次,GTK 允许开发者扩展和定制现有控件的功能。开发者可以通过继承现有控件类,并重写相应的方法来实现自定义功能。例如,开发者可以创建一个自定义的按钮控件,实现特殊的点击效果或行为。自定义能力满足了特殊需求。

2401_82943878的博客 1804
上一篇: Glade使用
下一篇: 物联网概述定义体系架构、与云计算关系
onnx
博客等级 码龄5年 1万+粉丝 416原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

onnx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值