问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何在linux下用gtk开发图形界面应用程序

发布网友 发布时间:2022-04-22 18:43

我来回答

1个回答

热心网友 时间:2023-10-25 02:44

  * 使用 GTK+ 和 Glade 快速开发 Linux 图形界面

  ** GTK+ 简介

  *** 基本概念

  GTK+ 是一种用于创建图形界面的库. 嗯, gnome 用的就是它, 不过并不是说只
  有在 gnome 环境中才能用, 只要系统上装有 GTK 的库 (基本上有图形系统的个
  人机都会有的啦) 就能运行基于 GTK 的程序. 除了 UNIX-like 平台, 它还移植
  到 windows 上, 还有面向嵌入设备的 framebuffer 版本等等.

  GTK 依赖两个重要的库. 一个是 GLib, 这并不是一个图形库, 也和 glibc 不同
  , 它大抵上提供了一些接口以屏蔽系统的不同, 比如 gint 在哪里都是 32bit
  的, 等等; 另一个是 GDK, 它是一个设备无关的图形库, 支持基本的画点, 以及
  与窗口管理器沟通等任务, 由于 GTK 被设计成能在各个平台, 而非仅仅在
  XWindow 环境下使用, 所以这个库也是必要的. 而在他们上面的 GTK 库, 就提
  供了一些 widget --- 可以理解为控件啦, 不过窗口也是一个 widget 的说, 给
  我们使用, 并提供了包装良好的事件响应机制.

  *** GTK+ 开发基础

  要开发基于 GTK 的软件, 必须先安装 GTK+ 的开发包. 检查是否正确安装的办
  法是在安装后执行 ``pkg-config --cflags --libs gtk+-2.0'', 如果安装不正
  确, 会提示找不到相应的包.

  GTK 本身是基于 C 的库, 当然也有 C++ 等语言的 wrap, 但它的整个体系是面
  向对象的. 其最基本的类是 GObject, GtkObject 继承了它, GtkObject 又派生
  出我们最经常用到的 GtkWidget, 我们使用的所有窗体控件都派生于它. 于是,
  在 C 环境中我们就要手动处理这些类转换, GTK 和底层的 GLib 等提供了一种
  统一的转换方法, 比如把类型为 GtkWidget* 的 button 转换成 GtkButton 形,
  写法是: GTK_BUTTON(button), 就酱子.

  我不打算在这里列一个 GTK 的 hello world 占页面, 这个程序随便 google 一
  下就能找到. 我们可以自己想一想一个图形界面应该如何建立.

  首先我们要进行初始化, GTK 提供了 gtk_init() 作为初始化, 它检查程序参数
  中的一些特定部分, 进行自己的设置. 调用方法如下:

  gtk_init(&argc, &argv);

  将 argc 和 argv 传指针的目的是 gtk_init 会对他们进行加工, 把 GTK 自己
  用到的一些参数抽取出来.

  接着, 我们必须要创建这些控件吧, GTK 中, 创建一个控件会返回一个
  GtkWidget 类型 (或它的派生类) 的指针, 所有创建控件的函数的格式是
  gtk_控件类型_new(参数表). 比如创建一个窗口的写法是:

  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  然后, 我们要设定事件响应函数, GTK 中的事件叫做 signal. GTK 的事件响应
  函数接口应该是类似这样的

  void
  destroy(GtkWidget *widget, gpointer data)

  我们把它连入到一个控件中的方法是这样的

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

  应该很好理解吧.

  我们创建的咚咚, 要说明他们的位置和包含关系, GTK 用 container 来解决这
  个问题, 它可以保证在窗口缩放的时候控件的摆放依然合理, container 的具体
  使用不详细说, 后面经常要跟 container 打交道, 但基本上不用管 C 代码, 嗯
  . 不过其实我们的任何的可视控件都继承自 container, 比如 button 也是一个
  container, 它很多时候装的是一个 GtkLabel, 也就是用来显示纯文本的控件,
  于是我们就能见到一个文本按钮, 嗯. 使用 container 的方法如下.

  gtk_container_add(GTK_CONTAINER(window), button);

  这样 button 就会占满整个 window 的控件, 我们后面可以看到可以用
  GtkVBox, GtkHBox 等 container 分隔窗体.

  好了, 我们可以准备启动程序了, 我们可以用 gtk_widget_show() 来显示各个
  控件, 然后我们就应该进入到所谓的事件响应循环了, 这就要使用 gtk_main().

  在程序运行过程中, 我们要操纵控件, 比如说我们要在一个 entry 控件(文本框
  ) 中取出其中的文字, 这样的操作使用 gtk_控件类型_动作(对象, 参数) 的形
  式完成的, 比如刚才所说的任务, 做法是 gtk_entry_get_text(entry).

  顺便讲讲 GTK 程序的退出, 关闭 GTK 的窗口 (即使是所有窗口) 也不代表程序
  退出, 因为那说到底只是一个界面而已, 我们当然可以使用 exit() 的自爆法退
  出, 但最好还是给 GTK 一个料理后事的机会, 在主窗口的 destroy 事件响应函
  数上用 gtk_main_quit() 就好了.

  编译 GTK 程序的办法也很简单.

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

  ** 使用 Glade 快速定制用户界面

  好了, 说了一堆有的没的, 如果我现在说我上面说的那一堆中的大部分我们都不
  会用到, 是不是觉得偶很歉扁? 前面的介绍只是给大家 GTK 这个库的一些基本
  概念, 概念就好了, 我们倒真的不用拿这些来编程的. 想想, 一个复杂一点的界
  面, 十几个控件, 再加上各种各样的 container, 自己挂事件, 再加上超常的命
  名, 想想都恐怖.

  这时候, Glade 横空出世了! 这是一个可视化的界面编辑器 --- 但它仅仅是一
  个界面编辑器而已, 甚至连代码编辑框也没有给出. 先不管了, 打开 glade (安
  装省略, 饶了我把, 记得装 libglade-dev), 应该很好懂了, 指指点点就能弄好
  一个界面, 然后在属性窗的信号一栏中选取需要的信号, 设定响应函数, 非常好
  弄.

  玩了几分钟, 问题来了, 怎么把它变为程序啊? 提供类似功能的 IDE 如
  Borland C++ Builder, 在点击创建新控件的时候, 我们能即使在代码窗看到自
  动生成的代码, Glade 也可以采用这种形式, 在设计好界面并保存后, 按一下主
  窗口的 build 按钮, 它就自动生成了界面代码, 根本不用自己写的. 打开代码
  目录, callbacks.c 里已经有自动创建的事件响应的空函数, 在里面填处理, 然
  后 configure make 就行了.

  但是, 这样的开发方式还是有问题的. 第一, 自动生成的代码非常复杂, 可是很
  多时候我们还是不能完全不看它, 处理和界面是混在一起了, 理解他们变得困难
  ; 其二, 由于以上的原因, 修改界面变得非常痛苦; 其三, 它给你生成那堆有的
  没的配置文件不一定是你想要的.

  因此 glade 提供了另一种方法, glade 编辑所得的 .glade 文件是一个 XML 文
  件, 其实它已经完整地描述了界面, 我们能否采用一种简单的方式直接载入, 配
  置它呢. 这样做, 我们的代码中就真真正正地去处了烦人的界面生成代码, 而专
  注于处理部分了.

  libglade 正是由于这个而来, 它能很好地完成上面所说的工作. 当我们用
  glade 创建了一个 .glade 界面后, 用这种方法我们就可以建立界面, 运行程序
  了.

  #include <gtk/gtk.h>
  #include <glade/glade.h>

  GladeXML *GUI;

  int
  main(int argc, char **argv)
  {

  gtk_init(&argc, &argv);

  /* load the interface */
  GUI = glade_xml_new("frame.glade", NULL, NULL);

  /* connect the signals in the interface */
  glade_xml_signal_autoconnect(GUI);

  /* start the event loop */
  gtk_main();
  return 0;
  }

  剩下的事情很简单, 如果你的 button 的 clicked 控件有一个响应函数
  on_button_clicked, 你写

  void
  on_button_clicked(GtkWidget *widget, gpointer data)
  {
  // balabalabala
  }

  就可以了. 所以, 上面讲的一堆创建界面的方法, 其实大部分时候都用不着.

  由于用到了 libglade, 我们的编译方法变为

  gcc -o foo foo.c `pkg-config --cflags --libs libglade-2.0`

  ** 开发举例

  一个很简单的程序, 密码学对称加密算法要用到的, 如果说是界面, 就是三个文
  本框: 明文, 密码, 密文, 三个按钮, 加密, 解密, 清除, 完了. 为了实验众多
  的算法, 我们加了一个下拉窗口, 用来选择算法. 我把它设计成一个 wrapper
  和框架, 它不实现任何算法, 只是在界面中获取用户输入, 调用外部程序, 并把
  结果显示出来而已. 这样, 实际的算法实现可以用纯 C 写的文本界面程序完成,
  移植起来很方便, 在 windows 随便做个一样的界面做前端就整个移植过去了.

  于是, 我们需要的窗体元素是 GtkEntry, GtkComboBoxEntry, GtkButton, 查查
  手册, 我们用到的界面相关的函数只有以下几个:

  - gtk_entry_get_text(), 用于获取文本框输入

  - gtk_entry_set_text(), 用于在文本框中显示结果

  - gtk_combo_box_get_active_text(), 用于在 ComboBoxEntry (派生自
  ComboBox) 取出用户选中的算法.

  另一个问题是, 他们都需要相应的对象指针做参数, 这应该怎样获得呢? 我们使
  用 glade_xml_get_widget(GUI, "控件名") 就能取得控件了.

  
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
八月中国最凉快的地方 八月份哪里最凉快,去哪旅游好?美丽的地方 乱字同韵字是什么意思 华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 cute ftp 8.0序列号 Cute FTP 8 怎样在linux图形化界面下安装程序 linux下怎样编写图形界面程序? 请帮我把这些句子译成英语,请用上提示单词。 cute英语怎么读音 如何用xmanager启动Linux上的图形界面程序 如何出现linux的安装程序界面 Linux下如何进行图形界面编程? 快手注销账号想找回可以找回吗 消防演练具体内容 跟据二次函数图像上三个点的坐标,求出函数解析式(要过程)? 明日将有明日之风吹拂什么意思 关于二次函数求解析式问题 根据二次函数图像上两个点的坐标,求出函数的解析式 已知二次函数的图像 消防演练注意事项 消防安全疏散演练的鸣笛声 根据二次函数图像上三个点的坐标,求出函数的解析式 (1)(—1,—1)(0,—2) (1,1) 求二次函数解析式 linux 图形界面 c语言 英语cute翻译的问题 Linux下有哪些图形界面编程的工具 Linux桌面程序损坏无法正常显示? handsome是什么意思? cute怎么翻译?? 如何在Linux桌面环境下自动启动程序 CUTE 全称是什么? 凶的组词有哪些 linux的程序需要在登录界面前启动 &quot;罪魁祸首&quot;的近义词大全 几个日常用语翻译成英语 Linux中怎么用c/c++做开发可视化程序 成语近义词罪魁祸首 制作linux 界面用什么软件好 罪魁祸首、 面目全非、生机勃勃 造句子 罪魁祸首的近义词是什么 英语答案 罪魁祸首意思相近的成语