GTK+ 3 基础知识学习

article/2025/9/11 12:16:52

1.启动程序

以前的版本要写一个GTK程序都是按照以下流程

int main(int argc, char *argv[])
{GtkWidget *window;gtk_init(&argc,&argv);... ...gtk_main();return 0;
}

现在最新的GTK+ 3.20的版本一般是按照以下格式初始,main函数里新建一个GtkApplication类app,并绑定activate回调函数,应用程序只需在activate写就可以了,main里的是启动代码,对于所有程序来说都是一样的。

int main(int argc , char **argv)
{GtkApplication *app;int app_status;app = gtk_application_new("org.rain.example" , G_APPLICATION_FLAGS_NONE);g_signal_connect(app , "activate" , G_CALLBACK(activate) , NULL);app_status = g_application_run(G_APPLICATION(app) , argc , argv);g_object_unref(app);return app_status;
}

这种方式在windows下有个问题,在activate设置断点时进不去,不知道什么原因。

2.新建一个窗口

代码不用过多解释,基本上看一眼就会,这里GTK_WINDOW (window)是把类型强制转换为GtkWindow,GtkWindow是GtkWidget的一个子类

static void
activate (GtkApplication* app,gpointer        user_data)
{GtkWidget *window;window = gtk_application_window_new (app);gtk_window_set_title (GTK_WINDOW (window), "Window");gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);gtk_widget_show_all (window);
}

效果如图

这里写图片描述

3.添加一个按钮

代码如下

static void
activate (GtkApplication *app,gpointer        user_data)
{GtkWidget *window;GtkWidget *button;GtkWidget *button_box;window = gtk_application_window_new (app);gtk_window_set_title (GTK_WINDOW (window), "Window");gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);gtk_container_add (GTK_CONTAINER (window), button_box);button = gtk_button_new_with_label ("Hello World");g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);gtk_container_add (GTK_CONTAINER (button_box), button);gtk_widget_show_all (window);
}

上述代码新建了一个按钮,并把按钮添加到window容器里
gtk_container_add (GTK_CONTAINER (button_box), button);
通过g_signal_connect设置回调函数,点击后会运行print_hello回调函数,并关闭窗口
这里写图片描述

4.容器控件

GTK中的所有元素都叫做控件,控件分为2种:

  • 容器控件
  • 非容器控件

非容器控件不能再容纳其他控件,如标签(GtkLabel)、图像(GtkImage)、画布(GtkDrawingArea)等界面编程中最基本的元素。而容器控件可以容纳其他控件,而上节中的window就是一个容器控件。

注意了!!

GTK中的容器控件又分为只能容纳一个控件的容器和能容纳多个控件的容器,如果在只能容纳一个控件的容器里添加多个容器就会出错。初学者一般会这样写程序,先新建一个窗口,然后再向窗口添加各种各样的控件。但是,窗口控件是一个只能容纳一个控件的容器,往上面添加了一个按钮后,再想添加一个按钮GTK就会报错。所以正确的做法应该是先向窗口中添加一个能容纳多个控件的容器,再向这个容器里添加所需的控件。

只能容纳一个控件的容器:

  • 窗口类
  • 对话框
  • 按钮
  • 框架
  • 事件盒

能容纳多个控件的容器又分为2种,一种是不能设定子控件的位置,但是可以设定控件的排放次序的容器,以盒状容器(GtkBox)为代表,它又分为横向排列和纵向排列的容器

  • 横向:
GtkWidget *hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
  • 纵向
GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

可以设定自控位置的容器有2种:

  • 自由布局控件(GtkFixed)– 能按固定坐标放置子控件的容器
  • 布局控件(GtkLayout)– 是个无穷大的滚动区域,能包含子控件,也能制定绘图

在实际开发中结合box容器和fixed容器通常能满足大部分需求。

5.设定按钮位置

可以通过fixed容器来完成,默认是在窗口的中央,现在设定在坐标(10,10)的位置

    GtkWidget *fixed = gtk_fixed_new();gtk_container_add (GTK_CONTAINER (window), fixed);GtkWidget *button = gtk_button_new_with_label("Button");gtk_fixed_put(GTK_FIXED(fixed), button, 10,10);

这里写图片描述
最后fixed容器有一个非常有用的功能,可以通过gtk_fixed_move来移动放在容器里的控件。

5.添加菜单

上面说了,窗口是一个只能容纳一个控件的容器,所以需要新建一个纵向的box容器,把菜单放在box的开头,其他内容放在下面

    GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);gtk_container_add (GTK_CONTAINER (window), vbox);GtkWidget *menubar,*menu,*menuitem;menubar=gtk_menu_bar_new();gtk_widget_set_hexpand (menubar, TRUE);gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, TRUE, 0);menuitem=gtk_menu_item_new_with_label("文件");gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);menu=gtk_menu_new();gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem),menu);menuitem=gtk_menu_item_new_with_label("新建");gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);g_signal_connect(GTK_MENU_ITEM(menuitem),"activate",G_CALLBACK(print_hello),NULL);GtkWidget *fixed = gtk_fixed_new();gtk_box_pack_start (GTK_BOX (vbox), fixed, TRUE, TRUE, 0);GtkWidget *button = gtk_button_new_with_label("Button");gtk_fixed_put(GTK_FIXED(fixed), button, 120,120);

这里写图片描述

6.设置背景图片

有2种方式,一种是把图片直接加载到fix容器里,这时界面会随图片的大小自动调整

    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("background.jpg", NULL);GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf);gtk_fixed_put(GTK_FIXED(fixed), image, 0,0);

另外一种是创建一块画布,把图片画到到画布上,这时超出画布的范围图片将不会显示,画图在回调函数中进行

GdkPixbuf *background;
static gint draw_cb (GtkWidget *widget,cairo_t   *cr,gpointer   data)
{gdk_cairo_set_source_pixbuf (cr, background, 0, 0);cairo_paint (cr);return TRUE;
}

cr是画笔,在回调函数里把图像赋值给画笔,再由画笔画到画布上

    GtkWidget* draw_area = gtk_drawing_area_new();gtk_widget_set_size_request(draw_area, 200,200);gtk_fixed_put(GTK_FIXED(fixed), draw_area, 0, 0);background = gdk_pixbuf_new_from_file("background.jpg", NULL);g_signal_connect (draw_area, "draw",G_CALLBACK (draw_cb), NULL);

这里写图片描述
这时还可以在别的地方在画布上画画,然后再通过gtk_widget_queue_draw (draw_area)来触发回调函数,对画布进行重绘

7.画一个圆

画布的回调函数里有一支画笔cr,可以用这个画图,但是这是私有的,其他地方不能使用,所以需要创建一个全局surface,这个surface与画布绑定,把图先画在surface上,然后在回调函数里把画布的画笔在surface上画图。注意在其他地方创建的画笔在surface上画图是显示不出来的,只有在回调函数里画图才能显示出来。

另外有一个问题就是画图一定要在gtk_widget_show_all(window);之后,在之前是画不出来的,具体原理还不是很清楚,猜想可能是configure_event事件需要在gtk_widget_show_all(window)之后触发,没有初始化是画不了图的。

cairo_surface_t* surface = NULL;
static gint draw_cb (GtkWidget *widget,cairo_t   *cr,gpointer   data)
{cairo_set_source_surface (cr, surface, 0, 0);cairo_paint (cr);return TRUE;
}int configure_draw(GtkWidget* widget, GdkEventConfigure* event) {GtkAllocation allocation;if(surface){return 0;//cairo_surface_destroy(surface);}else{gtk_widget_get_allocation (widget, &allocation);surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,allocation.width,allocation.height);}return TRUE;
}
    g_signal_connect (draw_area, "draw",G_CALLBACK (draw_cb), NULL);g_signal_connect(draw_area, "configure_event", G_CALLBACK(configure_draw), NULL);gtk_widget_show_all(window);cairo_t *cr;cr = cairo_create (surface);cairo_set_line_width (cr, 9);cairo_set_source_rgb (cr, 0.69, 0.19, 0);cairo_arc (cr, 100, 100,50, 0,2 * G_PI);cairo_stroke(cr);//先把图画在surface上,此时还不能显示图片,需要在draw_cb里显示cairo_set_source_surface (cr, surface, 0, 0);cairo_paint (cr);gtk_widget_queue_draw (draw_area);cairo_destroy (cr);

这里写图片描述

8.事件盒子

很多时候我们都需要鼠标点击来触发一个事件,但是除了按钮和窗口外,其他控件并不能绑定鼠标点击的回调函数,所以这时候事件盒子可以作为一个中间层,把需要鼠标响应的控件放在事件盒子里,再把事件盒子放在容器里,这样这个控件就可以响应鼠标点击的事件了

    event_box = gtk_event_box_new();label = gtk_label_new("点击这里,退出");gtk_container_add(GTK_CONTAINER(event_box),fixed);g_signal_connect(event_box, "button-press-event", G_CALLBACK(gtk_main_quit), fixed);gtk_fixed_put(GTK_FIXED(fixed), event_box, 100,100);

9.其他

透明按钮:
gtk_button_set_relief(GTK_BUTTON(button),GTK_RELIEF_NONE);

给按钮设置图片:
gtk_button_set_image(GTK_BUTTON(button), image);

隐藏控件:
gtk_widget_hide

获取父控件:
gtk_widget_get_parent(widget)


http://chatgpt.dhexx.cn/article/Y9cHT0aQ.shtml

相关文章

GTK+系列---Windows下的GTK+开发平台搭建(Win7 64位)

注意:这些说明适用于希望基于GTK开发应用程序的开发人员,而不适用于终端用户。 必要条件 Windows版本:GTK需要Windows 7或更高版本。对于旧版本的Windows,您应该自定义构建旧版本的glib和gtk。 我的安装平台为win7_64位&#x…

GTK+开发环境搭建

一般讲到GUI程序开发,大家都会想到C等面向对象的高级语言,而认为C语言不能做界面。C语言也可以用来写界面,GTK就是一个用来写界面的库,它本身就是用C语言写的,而且实现了面向对象的设计。对于一个C语言程序员来说&…

GTK官方教程

前言: 让你在开发中爱不释手的 GT 包。关注GSLS官网,查看更多源码 ヾ(✿゚▽゚)ノ工具包。 所有文章 小编尽量让读者可以 直接 读懂 与 完全 复制粘贴,其中复杂或较多 的源码 会有 源码 并 贴上 github 网址。 GT 类 里面…

GTK+入门教程

GTK入门教程&#xff08;一&#xff09; 1. 显示一个窗口 #include <gtk/gtk.h>int main(int argc, char *argv[]) {GtkWidget *window;gtk_init(&argc, &argv);window gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_widget_show(window);g_signal_connect(window,…

学习使用GTK+

学习使用GTK 0.概述 原文地址&#xff1a;http://blog.programet.org/2010/08/gtk-0.html GTK是当下流行的图形界面库之一&#xff0c;使用GTK可以方便地构造出应用程序界面。叶子觉得GTK很好用&#xff0c;在这里推荐给大家&#xff0c;并留下自己的一些使用心得。希望你也喜欢…

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

GTK&#xff1a;GTK的简介、安装、使用方法之详细攻略 目录 GTK的简介 1、GTK特点 GTK的安装 1、基于Windows平台安装 第一步、下载GTK 第二步、安装GTK 第三步、加载系统环境变量 第四步、运行命令测试 第五步、利用python预测测试 GTK的使用方法 1、C语言实现 2、…

【Linux】特别篇--GTK界面设计

【Linux】特别篇--GTK界面设计 一、GTK界面常用函数1、控件大小设置2、创建窗口3、创建控件&#xff08;1&#xff09;标签label&#xff08;2&#xff09;按键button&#xff08;3&#xff09;行辑器 二、GTK常用布局方法1、布局的使用方法&#xff08;以水平布局为例&#xf…

GTK入门教程

GTK入门教程 1.GTK简介 GTK&#xff08;GIMP Toolkit)是一套源码以LGPL许可协议分发、跨平台的图形工具包。最初是为GIMP写的&#xff0c;已成为一个功能强大、设计灵活的一个通用图形库&#xff0c;是GNU/Linux下开发图形界面的应用程序的主流开发工具之一。当然&#xff0c;…

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

今天花了一些时间复习之前学习过的gtk&#xff0c;感觉东西光学不用忘得好快啊&#xff0c;在这做个之前学过的内容的备份&#xff0c;希望对大家有用&#xff0c;也希望大家不要从入门到放弃。文中有些代码例子可能来自《GTK从入门到精通》吧&#xff0c;我不记得了&#xff0…

gcc下载地址

网上看到有提供的http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/&#xff0c;可以打开&#xff0c;但是下载太慢了 这里记录一个下载很快的地址https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/&#xff0c;为清华大学的开源镜像网站 想要找其他的开源软件&#xff0c;…

如何安装GCC

现在的CentOs8上没有自带的gcc编译器因此需要下载&#xff08;注意&#xff1a;这里的下载是指在虚拟机中下载&#xff0c;不是指在电脑上下载&#xff09; 若运行gcc时出现appstream 下载元数据失败则表明没有安装gcc。 1 首先需要获得root权限**** 在终端模式下输入su&…

arm-Linux-gcc交叉编译器和gcc编译器的下载地址

1.arm-none-linux-gnueabi-gcc下载 http://www.veryarm.com/arm-none-linux-gnueabi-gcc arm-none-Linux-gnueabi-gcc是 Codesourcery 公司&#xff08;目前已经被Mentor收购&#xff09;基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM系统中所有环节的代码&#xff0c;包…

Windows中安装GCC教程

GCC的安装教程 GCC简介 GCC编译器通常在Linux系统下使用&#xff0c;一般来说大部分发行的系统会默认安装&#xff0c;GCC编译器使用gcc指令在终端进行shell操作。 对于新接触Linux的朋友来说&#xff0c;简单的在Windows中练习过渡一下应该就足够了。&#xff08;我就是因为…

windows下安装gcc编译器(c/c++/fortran)

首先下载MinGW - Minimalist GNU for Windows 下载结束后双击&#xff0c;点击下一步即可&#xff0c; 然后勾选要安装的组件&#xff1a; 点击应用&#xff1a; 开始安装&#xff08;这一步要经过漫长的下载过程&#xff0c;请耐心等待&#xff09;&#xff1a; 修改环境变量…

软件安装 gcc编译器

rpm命令及各参数使用。针对所有已安装的软件建立一个本地软件数据库&#xff0c;作为后续软件升级和卸载的依据本地软件数据库保存在目录/var/lib/rpm中 yum命令及各参数应用可以把本地计算机作为本地YUM源&#xff0c;也可以配置一个网络YUM源 YUM源&#xff1a;包含整理好的…

在线c++编译器(gcc)

这几年c标准委员会活跃起来&#xff0c;c11、14标准相续推出。对于想尝鲜又怕麻烦&#xff08;visual studio 更新慢&#xff0c;对标准的支持力度也不够。对于使用gcc的&#xff0c;替换系统的gcc版本或者安装个mingw也挺费事&#xff09;的人来说&#xff0c;可以优先考虑在线…

GCC编译器介绍

GCC是一套由GNU开发的编程语言编译器&#xff0c;在Linux系统下可以用它调用其他不同的工具进行预处理、编译、汇编、链接这样的工作&#xff0c;其执行效率比一般编译器高20%~30%。由于它是GNU项目之一&#xff0c;是开源的软件&#xff0c;我们可以直接从网上免费地下载安装它…

Window10-MinGW下载安装gcc,g++编译器

文章目录 完成流程步骤&#xff1a;出现的问题&#xff1a; 完成流程步骤&#xff1a; 1.MinGW下载 MinGW官网 mingw-get-setup.exe下载地址 2.MinGW安装 打开下载好的mingw-get-setup.exe &#xff0c;这里选择安装目录为F:\MinGW。 3.下载安装gcc/g ​ 通过MinGW Insta…

gcc官网以及各个版本下载地址

gcc的官网&#xff1a; http://gcc.gnu.org/ gcc镜像站点&#xff1a; https://gcc.gnu.org/mirrors.html 例如点 Japan的链接 到japan站点下载

GCC编译器 MinGW的下载安装使用教程

哎 总所周知 gcc可以用来编译C 和C。在linux广泛应用&#xff0c;那么window怎么使用gcc呢。 就要用到gcc的window工具----MInGW&#xff0c;安装好之后&#xff0c;直接可以在windows的dos界面编译。 下面讲解安装使用过程。 1.官网下载 MinGW - Minimalist GNU for Windows d…