2

GTK学习心得

 2 years ago
source link: http://antkillerfarm.github.io/technology/2014/12/26/gtk_study.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

GTK学习心得

2014-12-26

1)安装环境

本人所使用的开发环境是Ubuntu 12.04。默认情况下已经安装了GTK+3开发所需的包。可以使用pkg-config --cflags --libs gtk+-3.0来确认安装的有效性。

阅读示例代码是学习GTK+3的有效途径。可使用sudo apt install gtk-3-examples安装相关的示例代码。

2)Glade

Glade仍然是GTK+3默认的UI设计工具。与GTK+3配合的Glade版本是Glade 3。但是与Glade 2不同的是,Glade 3不再生成相关的C代码,取而代之的是一个描述UI的XML文件。因此,多年前积累的使用经验已经不起作用了。需要从头学起。

在GTK官网的GTK+ 3 Reference Manual中的Getting Started with GTK+一节,提供了如何使用Glade布局文件的例子。但实际上Glade除了布局之外,也支持消息映射的定义。例如,我们完全可以在Glade中定义某个按钮的点击事件的回调函数,而无需再使用g_signal_connect函数去链接消息和回调函数。

不过,如果在Glade中使用了该特性的话,相关的编译选项亦需要调整。

pkg-config --cflags --libs gtk+-3.0

pkg-config --cflags --libs gtk+-3.0 gmodule-export-2.0

这样修改之后,程序即可自动链接相应的回调函数。另外还要注意,用户定义的回调函数的定义需与文档中消息回调函数的原型一致。一些细微的差异会导致g_signal_connect函数显式指定的回调函数可以正常工作,但glade文件隐式指定的却不行。

此外,如果是在Windows平台下使用GTK+,还需要在回调函数之前加上G_MODULE_EXPORT宏。

3)事件回调函数

事件回调函数一般包括两个参数,第一个是产生事件的Widget的指针,第二个是用户自定义的数据的指针。可以将需要传递的数据用这个指针传递。如示例(http://code.google.com/p/antkillfarm-source-pool/source/browse/tags/first_demo.7z)中的do_cmd_itouch函数所示。

4)如何获得某个控件的指针

事件回调函数只能返回一个用户数据指针,有的时候某个按键动作会同时对几个控件进行操作。这个时候就需要通过某种方式来获得各个控件的指针。

如示例(http://code.google.com/p/antkillfarm-source-pool/source/browse/tags/first_demo.7z)中的do_cmd_ipod函数所示:

1–首先在Glade中,将main_box的指针设为用户数据指针。

2–使用gtk_container_get_children函数获得各个子控件的指针链表。

3–GTK中使用GList类型来表示双向链表数据结构。可使用g_list_first获得链表的头结点。但是需要注意

g_list_next函数的参数是当前节点main_box_child,而不是链表的指针main_box_children_list。这个类型的相关函数中并不存在一个类似枚举器的概念。

4–gtk_widget_get_name函数返回的是控件的类型名,例如GtkLabel。gtk_buildable_get_name函数返回的才是控件的id,例如label_hello。显然只有根据Glade文件生成的控件才有id。

5)多窗体开发

单窗口GTK+程序的编程,很快就掌握了。下一步开始实践点击一个按钮,生成一个新窗口的功能。网上的例程多数都是基于GTK+ 2的。由于GTK+和Glade的版本升级,这样的方式虽然仍然可用,但却不再是最简便的方式了。

首先还是使用Glade编辑ui文件。一个ui文件可以包含若干个窗口定义。调用gtk_builder_add_from_file生成这些窗口的数据 结构。可以将生成的窗口结构通过user_data的方式传递给按钮的回调函数。但是需要注意的是,传递给回调函数的窗口结构必须是有效的。

例如,在ui文件中,将B窗口结构传给A窗口中的C按钮的回调函数。程序运行时,首先点击C按钮,弹出B窗口,然后关闭B窗口,并再次点击C按钮,结果什么反应也没有,B窗口并未如预期般弹出。

经分析方知,关闭B窗口的时候,B窗口的数据结构被销毁,从而不再有效。因此如果想要再次弹出B窗口的话,就只有两种办法:

1)重新创建B窗口的数据结构。

2)重载B窗口的关闭消息,让它只是隐藏而不是销毁窗口。

对于第2种方案,网上的例子很少,有也基本都是重载窗口的destroy信号。但实际上delete-event才是关闭事件的信号,只有做完了delete-event才会执行destroy。这一点在GTK的用户手册上有详细的说明。同时,手册还推荐使用 gtk_widget_hide_on_delete函数来实现第2种方案。

6)change-value和value-changed

GtkScale有两个容易混淆的事件:change-value和value-changed。

两者的区别是,change-value是一个主动事件,只有用户通过GUI操作控件才会触发;而value-changed是一个被动事件,无论什么原因,只要改变控件的值,就会触发。

https://blog.csdn.net/taiyang1987912/article/category/5778511

一个GTK的专栏

2020.7

有4年半时间没有上GTK官网了。这回GTK和Gnome的官网,都改了风格设计,不再是10年前的老样子了。

GTK4已经出了4个预览版,看起来就要正式发布了。从API层面来看,加入了MVVM的设计,CSS应用的也更广了。

12年前,我接触GTK,主要是为了学习Linux GUI编程。

7年前,我研究GTK,开始将工作从Windows转向Linux,那时的目标是写出两个平台都能跑的软件。cygwin/makefile是这时的常客。

5年前,工作全面转入Linux,Windows+Virtual Box。家用双系统。

3年前,工作电脑双系统,几乎不用Windows。

在Windows下使用GTK+3

2013.9

1)安装MinGW

我比较偷懒,之前安装Qt SDK的时候,已经有了个MinGW环境,直接拿来用就可以了。

2)下载GTK+3 for Windows

http://www.tarnyko.net/

下载GTK+3的包。

该网站是个法国佬办的。在www.gtk.org官方的维护GTK+ for Windows的人员闪人之后,这是少数几个移植GTK+3到Windows,且成功的版本。

该网站还有一篇GTK+3 Installation Tutorial for Windows的文章,介绍如何安装他制作的GTK包。里面还附带有一个Hello World程序代码,对于初始的学习很有帮助。

3)优化自己的开发环境

在mingw文件夹下新建MinGW.bat文件,内容如下:

set PATH=D:\QtSDK\mingw\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;D:\gtk+-bundle_3.6.4-20130513_win32\bin
cmd

除了几个Windows的系统路径之外,把MinGW和GTK的路径加进去就可以了。

把mingw32-make.exe复制一份,并改名make.exe,就可以如同在Linux环境下一样,使用makefile文件控制编译过程了。

4)如何去掉执行文件时的命令行窗口?

编译时添加-mwindows选项,就可以只启动gtk窗口,不启动命令行窗口。

5)找不到-lintl该怎么办?

到opensuse的官网下载mingw32-libintl的rpm包。用7-zip解压安装到gtk包中即可。

GTK & OpenGL

众所周知,OpenGL只是一个图形渲染库,没有对于窗口系统的支持,而glut等也只是提供了最基本的窗口操作,使用起来并不方便。因此最好的做法是在一个成熟的GUI库的基础上添加OpenGL的支持。

GTK 2下使用OpenGL,可以考虑使用GtkGLExt。但该软件并不支持GTK 3。

按照GTK 3官方的说法,他们计划在2015年4月发布的GTK 3.16中集成对于OpenGL的支持,但实际上相关的支持代码已经于2014年12月17日,由Chun-wei Fan提交到版本库中。

搜了一下,Chun-wei Fan是一位台湾同学,因为他的邮箱是台湾Yahoo的。但估计不是linkedin中的哥们,那个人虽然也是搞IT的,但偏重Java和网页方面的开发。

从git log来看,这个Chun-wei Fan是GTK的骨灰级提交者,提交次数240+,从2010年11月就开始提交,提交内容多集中在GTK的Windows移植上,尤其是如何使用VS来编译GTK。

但是编译GTK工作量较大,对于我这样临时抱佛脚的人来说,起不了什么作用。

于是我打算用最简单的方法,解决在Windows平台下,GTK 3对于OpenGL的支持。

我主要参考了以下文章:

http://garfileo.is-programmer.com/posts/25812

这篇文章讲述了如何使用GLX,向GTK 3中添加OpenGL支持。考虑到在Windows下,MS提供了WGL作为GLX的等价物。因此我们只要将该文章中与GLX相关的内容用WGL替换掉,理论上就可以在Windows平台上,提供对GTK 3的OpenGL支持。

参考文献还包括:

1.http://msdn.microsoft.com/en-us/library/windows/desktop/dd374204(v=vs.85).aspx

这篇文章讲述GLX和WGL函数之间的对应关系。

2.http://msdn.microsoft.com/en-us/library/dd318258(v=vs.85).aspx

这篇文章提供了一个最简单的GLX的例子,并给出了在WGL下的等价代码。

移植成功的代码放在:

https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/gtkglx

用户需要根据自己的实际情况,修改Makifile.w32中的相关路径,把GTK和MINGW的路径设置好。


2021.12

GTK 3.16+的示例如下:

https://github.com/ebassi/glarea-example

GTK与系统图标

在GTK 2.x时代,用户可以通过一系列的stock API来调用GTK自带的图标,比如gtk_tool_button_new_from_stock函数。

到了GTK 3.x时代,GTK使用Icon Theme取代了之前的stock。不光函数名发生了变化,就连参数中名称的字符串也发生了变化。stock时代,将相关字符串定义为C语言的宏。而Icon Theme时代,需要在/usr/share/icons目录下,查找所需要的图标,然后把图标的后缀名去掉,即可得到相关字符串。

Icon Theme系统的关键是各个目录下的index.theme文件。

GTK嵌入网页

GTK嵌入网页的方案,主要有两种:GtkMozEmbed和WebkitGtk。

GtkMozEmbed调用Mozilla的Gecko内核渲染网页,这个方案在2008年以前比较流行。但近些年来,由于Webkit的流行,该方案已经日趋式微,最新版本仍然停留在2008年。

WebkitGtk调用Webkit内核渲染网页。它的安装方法:

sudo apt install libwebkitgtk-3.0-dev

注意这里需要根据你的gtk环境和Webkit API的版本选择不同的包。比如Gtk 2.x选择libwebkitgtk-dev,Gtk 3.x+Webkit 2选择libwebkit2gtk-3.0-dev。

例子参见:

https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/gtk_browser

这里有两个例子,一个是helloworld型的,用于确定开发环境。另一个是从

http://imtx.me/archives/1124.html

中摘录的,原始的版本基于Gtk 2.x,现在改用Gtk 3.x。

GIO网络应用开发

GIO提供了以GSocket为首的低级API,和以GSocketClient、GSocketConnection为首的高级API。

高级API的使用示例如下:

https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/helloworld/glib/network


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK