My Gtk Tutorial 2

我写这些其实我真的自己都不看的,有用还是没用只有我唯一的那个目标读者来评价。

那么我们来无聊的介绍下Gtk的一些Widget。

1、GtkBox

和 Qt 不同的是,Gtk一般实现一个自己的Widget,都是从一个具体的Widget而不是general的GtkWidget 开始的,其中很多则又是选择了 GtkBox。

当然这里所说的实现一个具体的Widget不是指连draw事件都override的那种widget,而是一组widget的组合,例如文件对话框这种。那么具体实现的时候只要找好你要的那个顶层的Widget作为基类就行了。

曾经的 GtkHBox 和 GtkVBox 已经成为了历史,取而代之的是以一个横纵作为属性的 GtkBox。

一般而言,任何你想要的复杂的布局都可以用GtkBox来实现,一个技巧就是占位符,看起来Gtk里面并没有Qt的Spacer这种专门的占位符,一般用来占位的就是GtkLabel。

例如你希望实现一个上下顶头有Widget的东西,中间是空的,那么你可以new一个Vertical的GtkBox出来,然后使用  gtk_box_pack_start 往里面扔东西。中间用一个GtkLabel来撑开位置。

2、大小

写UI控件最头疼的事情是什么?是大小。说他们的定位难度堪比HTML也不为过。尤其是在你没注意到的时候你把你的窗口设置成为可拖拽,或者进行i18n后出现了一些惨烈的情况(单从语言来说,同一个词,一般汉语最短,英语次之,某些西语会长的要命)。

不过在Gtk3中,GtkWidget终于增加了expand,align,这些用来标明Widget本身的大小和位置属性。

这下终于要谢天谢地了?哦,其实没有,如果你的界面够复杂你可能还是想要掀桌(不过如此的话你是不是应该先考虑下你的设计?),不过也比Gtk2时代好的多就是了。

在处理大小时要考虑到你在进行i18n之后界面可能产生的变化……

处理大小时,GtkBox的默认是参考内部的Widget的属性来确定的,而Gtk2的兼容类GtkHBox,GtkVBox还默认并非如此。

总之这两个属性也不难理解,就是给你一个较大的空间。你的Widget是保持较小状态,还是填满整个区域?是如何在这个区域内进行对齐的?

3、来实现个Widget吧

如果你了解GObject的继承,那么这一步对你来说基本是没有难度的。

如果你不了解GObject的继承,还是去看别的文章吧……

http://garfileo.is-programmer.com/categories/6934/posts

C语言模拟继承是采用了一个非常简单的方式,就是struct的嵌套,在所有模拟继承关系的代码中都采用了这样的方式,这样做的好处就是你可以强制转换子类的指针为基类的指针。

struct Derived {
     Parent parent;
};

这样你就可以简单的去访问parent的值了。至于如何实现private,这里也简单说下。

struct Derived {
     Parent parent;
     Private* priv;
};

然后采用前向声明声明Private,Private的定义则写在c文件里面,而不是h里面,这样就可以保护Private内部是不可见的。当然如果你的类压根就不会给别人用,你也没必要非要用Private。

实现自己的Widget基本上来说,就是定义一个你要的Class的子类的过程,过程非常简单,你大可找个GObject的Skelton的生成器来帮你生成主干代码。

然后在init部分老实填入你自己的内容,写一个自己的new函数(虽然里面无外乎就是g_object_new的wrapper)。

下次来讲个具体类的实现。

Posted in Gtk | 13 Comments

My Gtk Tutorial 1

大概我这样的人还是超少见的,或者你可以称之为傲娇。

于是这个是我自己写Gtk程序的心得。我个人的主力发行版是一个几乎无Gtk的发行版,平时唯一用于测试gtk的程序其实是gtk-demo。不过即使如此我也照样开发着Gtk程序,不过由于发行版没有Glade,虽然用下也不会少块肉,不过界面大部分还是靠手写。反正就是省点事情。

本文基于 Gtk3 和 up to date 的 Glib。

另外我对于所有动态语言抱有一种不信任的态度,另外就是写C比较熟悉,所以还是写C。

那么开始第一个程序吧。

在最新的GLib中,GLib终于也诞生了一个称为Application的概念,对于Gtk2时代的人来说这大概是个没听过的概念。用了有什么好处呢?

1、支持单实例
2、支持Application Menu

说道Application Menu,这究竟又是个什么东西呢?可以理解为“属于这个程序的”菜单,例如Firefox,Opera的大按钮等等。

当然不幸的是,我最近唯一写的Gtk程序是不需要Menu的,而且反正这个功能在非GNOME3环境下惨不忍睹(显示为只有一项的菜单栏,要多难看有多难看),所以这里带过不提。

那么第一个GtkApplication就从这里开始:

https://github.com/fcitx/fcitx-configtool/blob/b68086d4b6773845065e44956875d90bca195eba/gtk3/main.c

(该死的WP贴代码不方便)

如果你用过 Qt 的话,大概就看出了

QApplication app(argc, argv);
app.exec();

的影子,总之就是差不多的东西。

这里还实现了一个函数,activate,这个函数会在执行程序的时候被调用,而且是交给主进程的程序,于是里面的内容很简单,如果有窗口,那就显示出来,如果没有,那就创建一个。

关于 GObject 的 Signal,在下不才其实并不十分了解,你可以参考:

http://nanjingabcdefg.is-programmer.com/posts/24116.html

activate 本身其实也是一个 signal,具体你要实现activate被调用的效果其实有很多方式,在这个小地方怎么实现其实都并无所谓,你可以自己g_signal_connect 一个上去,或者采用别的方式。

但总之单实例就是这么简单就可以用上了。

里面的window部分是我自己实现的window,你如果想要随便测试玩玩的话,可以用 gtk_window_new 随便搞一个简单的出来。这里和Qt的一个差别是,top level的需要是GtkWindow,而Qt里面Toplevel的只要是Widget就可以了。

那么另一个可能的需求就是,你想要处理参数,这里让我当年好是头疼了一会。

那么再来看代码吧。

https://github.com/fcitx/fcitx-configtool/blob/1837cdf9bd0e03e05569c899e09ac9c4e024eb6a/gtk3/main.c

这里我处理参数处理的很简单,就是打开了一个fcitx对应addon的配置窗口。

这段代码存在了许多非常magic的地方,首先是创建Gtk程序的FLAGS变了,变成了,

G_APPLICATION_HANDLES_COMMAND_LINE

首先说明你需要command-line的支持。

其次,由于程序变成了单实例,于是就出现了local-command-line和command-line两个signal,其一,是在当前进程处理的,第二个则是在单实例的程序那边处理的。

这里我们并不需要local处理,于是跳过。然后这里就是magic的地方,当这个flag存在时,activate是不会被自动调用的,于是可以看到我在 fcitx_config_app_handle_command_line 手动调用了activate,然后进行了打开addon窗口的处理,第一次写这个的时候我迷惑了好半天……不如说是默认处理command line的行为就是activate,如果使用了这个flag的话这个行为将被discard而需要自己操作。

至于具体的参数处理,虽然glib也给了一些函数进行处理,不过我还是不善于此道,就直接用了第一个参数。

P. S.

至于这些和浆糊一样的内容究竟是有用还是没用呢?谁知道啊。

有没有2呢,谁知道啊。

Posted in Gtk | 17 Comments

Fcitx 4.2.4

fcitx 4.2.4
1. fix some xim problem
2. add fcitx-gclient for glib and gir binding, can be used to control fcitx or implement fcitx client.
3. merge fcitx-keyboard into fcitx
4. bind specific keyboard layout with inputmethod (you need up to date fcitx-configtool,gtk3 ver or kcm-fcitx to configure this feature)
5. adjust some default hotkey setting.

NOTICE, if you’re using some custom xmodmap script, and if you don’t want to be affected, please disable “override XKB system setting”. Only xkb option is supported for now.

1、修复一些xim的问题。
2、增加fcitx-gclient,提供了glib和gir的绑定,可以用于控制fcitx或实现fcitx的client。
3、fcitx-keyboard 合并进 fcitx
4、将特定键盘布局和输入法绑定(需要最新的fcitx-configtool,gtk3版和或者kcm-fcitx来设置这个功能)
5、修改一些默认设置

注意,如果你使用自定义的xmodmap脚本,并且不希望受到影响,请禁用“覆盖系统XKB设置”,目前fcitx-xkb只支持xkb option里面的设置不受影响。

fcitx-configtool 0.4.4
1. fix a potential crash with newer gtk3
2. rework gtk3 version UI,  able to configure input method from input method page

1、修复一个潜在的崩溃问题
2、重新修改gtk3版的界面,支持从输入法页配置输入法

kcm-fcitx 0.3.4
configure input method from input method page

支持从输入法页配置输入法。

fcitx-table-extra 0.3.1
1. adjust some quick-classic hotkey
2. fix some error in scj6
3. add wubi-large for large charset

1、调整速成古典版的快捷键
2、修复仓颉第六代的一些错误
3、增加五笔大字集的码表

fcitx-table-other 0.2.0
add more table from scim-table

从scim-table移植更多码表

fcitx-sunpinyin 0.3.7 + fcitx-cloudpinyin 0.2.2
need sunpinyin git master to save cloudpinyin result to sunpinyin userdict.

需要sunpinyin的git master,支持将cloudpinyin的输入法保存到sunpinyin用户词典中。

Posted in fcitx development | Tagged | 12 Comments

这里有一个好消息和一个坏消息

好消息就是新版的ATI驱动终于可以用kwin的direct rendering了

坏消息是我正在用着一个本子,双显卡,两个显卡都是ATI的,不过有一半……是不被这个驱动支持的显卡了。

我好想要intel的本子……

Posted in Linux | 7 Comments

Think more

当你发现了一件好事的时候,是否这件好事本身就是最终的目的这是值得商榷的……

世界上无数事情和它的本意是不同的。例如说我开发一个feature,你可能并不知道我最初的目的是workaround一个bug。

来我们来顺带定义一下某种可以被称作“脑残粉”的行为。

主体A,做了事情B,导致了结果C,然则由于C的结果是好的,于是“你”就说A真是好啊。这是例一。

例二,主体A,做了事情B,导致了结果C和D,然则由于C的结果是好的,而D的结果是不好的,仍然由于C是好的,于是“啊,这是没办法的嘛”,或者干脆的选择性无视D。

那么无论是例一,还是例二,都无视了主体A本身想要达到的目的。究竟是无心插柳还是有意为之其实是并不知道了(即使主体A“宣称”如此)。

甚至可能结果D才是主要目的。

P. S.

话说写这种喷文的目的之一就是开地图炮而隐藏我真实想喷的人的意图,比如如果你认为我的目的是喷果粉之类你就too simple了。比如之前的某篇也是如此。

开地图炮的好处之一,就是让人产生“是不是在说我”的感觉……于是达到的效果也许可以超过预期。

 

P. S. 的 P. S.

那么我写 P. S. 目的是文字的表面含义吗?如果你思考到了这点大概我也没白写。

Posted in 日志 | 14 Comments