[MagPi 89期] 基于GTK工具包自定义Linux GUI窗口部件

文章信息

本文翻译自The MagPi 89期(2020年01月刊)- Tutorial

原文标题: Custom widgets with C and GTK

原文作者: Simon Long — 软件工程师,受雇于树莓派公司,负责Raspbian和Debian环境的树莓派桌面开发

翻译: 启莘风

点击文章末端“阅读原文”可获取原文(若无法跳转可用浏览器打开)。

欢迎各大论坛网站转载分享。

转载请注明原文作者及中文译文出处,并以原文超链接或二维码形式注明中文译文出处:启莘风。


The MagPi杂志简介与译者注

MagPi是面向创客的终极杂志,它包含以Raspberry Pi为主题的创新项目、评论、教程、操作方法以及新闻和活动。

2012年,MagPi作为树莓派社区的杂志,由爱好者发行。现在由Raspberry Pi官方认可并发行,每月一刊。现已成为市场上最畅销的计算机杂志之一。对于任何对技术有浓厚兴趣的人来说,这都是不错的选择。

网络上不乏众多爱好者对多期MagPi杂志进行了汉化,但因为各种原因,大多都已暂停或停止了更新。本号启莘风将从2020年1月刊(第89期)开始,对每期杂志的文章进行汉化翻译,旨在为国内的创客和树莓派开发者们提供实用的中文学习资源,分享国内外的树莓派应用案例。希望此举能够激发更多的创新灵感,期待得到各位的支持。

image

GTK工具包函数功能示例

“更改小部件的属性,以更改其外观。”

到目前为止,在树莓派所有示例中,我们都使用默认状态的小部件。我们通过调用 gtk_<widget name>_newfunction建了小部件并使用了它。但是,GTK确实通过设置每个小部件的属性来允许一定程度的小部件的自定义。

作为示例,我们将看一下基本GtkButton小部件的一些属性。试试这个例子:

void main (int argc, char *argv[])
{
gtk_init (&argc,  &argv);
GtkWidget  *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkWidget  *btn = gtk_button_new_with_label ("Close window");
g_signal_connect (btn,  "clicked", G_CALLBACK (end_program), NULL);
g_signal_connect (win,  "delete_event", G_CALLBACK (end_program), NULL);
GtkWidget  *btn2 = gtk_button_new_with_label ("My button");
g_object_set (G_OBJECT (btn2),"relief",GTK_RELIEF_NONE, NULL);  # highlighted line
GtkWidget  *box = gtk_vbox_new (FALSE,  5);
gtk_box_pack_start (GTK_BOX (box), btn2,TRUE, TRUE,  0);
gtk_box_pack_start (GTK_BOX (box), btn,TRUE, TRUE,  0);
gtk_container_add (GTK_CONTAINER (win),box);
gtk_widget_show_all (win);
gtk_main ();
}

这是先前示例中熟悉的代码,但是高亮的行是新的。

g_object_set将小部件的名称作为参数,然后是以 NULL终止的属性名称和属性值列表。在这种情况下,我们将GtkButton btn2的浮雕属性(relief property)设置为 TK_RELIEF_NONE(参见图1)。

图1 一个GtkButton,其浮雕属性设置为 `GTK_RELIEF_NONE`

GtkButton的“浮雕”属性控制边框的外观。一些GTK小部件的边框周围应用了一定程度的阴影以提供3D外观。在默认情况下,GtkButton启用了此阴影,这使按钮看起来与窗口背景略有不同。通过将浮雕设置为 GTK_RELIEF_NONE,该3D阴影将被删除。如果您运行上述程序,则应该能够清楚地看到窗口上两个按钮之间的区别。(您可以使用TAB键在按钮之间移动虚线轮廓以更清楚地显示差异。)

下面是另一个例子。删除浮雕属性的设置,并通过添加下划线更改按钮的名称:

GtkWidget *btn2 = gtk_button_new_with_label ("My_button");

您应该最终得到一个类似于图2的按钮。

图2 一个GtkButton,在标签中带有下划线,并且 `use-underline`属性设置为 `FALSE`

如果现在设置 use-underline(设置下划线)属性:

g_object_set (G_OBJECT (btn2),"use-underline", TRUE, NULL);

下划线将消失,但是如果您按住键盘上的ALT键,则下划线会再次出现在“按钮”的“ b”下方(图3)。

图3 相同的GtkButton,但 `use-underline`设置为 `TRUE`

所有小部件都具有可以像这样设置的属性。再举一个例子,尝试用GtkLabel替换GtkButton:

GtkWidget *lbl = gtk_label_new ("My label");

然后将标签的角度属性(angle property)设置为45度:

g_object_set (G_OBJECT (lbl), "angle", 45.0, NULL);

请注意,将角度输入为45.0而不是仅输入45是很重要的。因为期望的值是浮点数,在值的末尾添加“.0”,可确保编译器将输入值其视为浮点数。

程序运行完毕后,应该弹出一个如图4所示这样的窗口,标签文本与水平方向成45度角(图4)。

图4 一个GtkLabel,其角度属性设置为45.0

在许多情况下,小部件还具有专用的功能来设置每个属性,以代替通用的 g_object_setfunction函数(在上面的示例中,分别为 gtk_button_set_reliefgtk_button_set_use_underlinegtk_label_set_angle)。g_object_set的优点在于,它可以用于在一行中设置多个属性,这可以大大缩短您的代码。

每个窗口小部件的GTK在线文档页面列出了所有属性和专用函数以设置其值。对于上面的两个示例,可以在magpi.cc/GtkButton和magpi.cc/GtkLabel上找到。值得一看的是您要使用的任何小部件的选项。这些页面也是找出与小部件交互时,小部件产生什么信号的好方法。

GTK工具包主题使用简介

可以自定义GTK小部件的另一种方式是使用主题。主题会影响每个GTK应用程序中小部件的每个实例的外观,而不是一次更改单个小部件的外观。

在Raspbian(以及大多数其他Linux桌面发行版)中,在目录 /usr/share/themes中安装了一系列主题。

该目录包含许多命名文件夹,每个文件夹都是GTK或其他主题应用程序的主题。如果命名文件夹包含名为“gtk-2.0”的子文件夹,则该文件夹的名称也是有效的GTK 2主题名称。

GTK应用程序当前使用哪个主题通常由xsettings daemon守护进程控制,该进程在后台运行,并向所有桌面应用程序提供配置信息。在Raspbian上,要更改在守护进程中设置的主题,您需要更改配置文件中的值。

为此,请检查目录 ~/.config/lxsession/LXDE-pi中是否存在名为desktop.conf的文件。如果没有,请通过将文件 /etc/xdg/lxsession/LXDE-pi/desktop.conf复制到该目录中来创建一个。

然后,如果您使用文本编辑器查看desktop.conf文件,则会出现标题为[GTK]的部分。在该标题下的某处是以 sNet/ThemeName=开头的行,默认情况下,在Raspbian上该行设置为PiX。如果您在此行中将PiX更改为另一个GTK +2主题的名称( /usr/share/themes中的包含了gtk-2.0子目录的任何目录),则正在使用的主题将自动更新,并且您应该能看到每个GTK应用程序正在以新主题重新运行。

创建主题不适合缺少经验的开发者,但是如果您有兴趣,可以在目录 /usr/share/themes中的任一gtk-2.0子文件夹查看。主题本身位于此文件夹中的名为gtkrc的文件中。可能还有许多其他子文件夹,其中包含该主题使用的图形元素和其他资源。

gtkrc文件是纯文本文档,可以在您选择的编辑器中打开。其中大多数包含许多样式定义,其中包括文字样式和大括号中包含的几行。文件的末尾是将小部件与先前定义的样式相关联的行。

要更改小部件的外观,请在文件末尾的关联列表中找到它,并注意对其应用的样式。然后在文件中找到该样式的定义,然后尝试更改一些参数以查看会发生什么。在执行此操作之前,请备份原始的gtkrc文件,或更好的备份方法是,复制整个主题文件夹,并为其选择一个新名称。将desktop.conf中的 ThemeName设置为新主题的名称,然后通过修改现有主题创建自己的主题!


本号启莘风将从2020年1月刊(第89期)开始,对每期杂志的文章进行汉化翻译,旨在为国内的创客和树莓派开发者们提供实用的中文学习资源,分享国内外的树莓派应用案例。希望此举能够激发更多的创新灵感,期待得到各位的支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容