Gtk

Gtk 修改GtkLabel、GtkEntry等的文本颜色,添加下划线,更改字体大小等相关属性

代码如下,将Widget传进函数即可,之后相关属性会相应改变.

详情见注释

也可以进一步封装,根据widget类型,自动调整逻辑,同时适应Entry和Label等的属性设置:

Continue reading...

记录一次奇怪的段错误经历

背景

GTK编程,在函数内部定义了一个结构体,作为指针传递给其他函数,在其他函数内部调用结构体内部成员变量,发现有一个成员变量总是为空,另外一个不会。

 

原因

定义结构体的位置在回调函数内部,回调函数运行完成后,结构体所在内存即被回收。

然而有时候在一定时间内回收内存里的数据没有发生改变,所以有些结构体的成员变量还是能够正常获取。

但是在执行其他指令的时候,原结构体部分成员变量的内存会被重用,造成内部数据改变,再去调用的时候,得到的就是完全随机的数据,如果把它当做指针使用,它指向的内存是未知的,未被申请的,再去操作这段内存就会发生段错误。

 

解决办法:

将结构体定义成 static 类型,让他在程序的整个生命周期内有效,不会被回收。

Continue reading...

Gtk searchEntry 无法输入英文文本

–Gtk searchEntry 无法输入文本可能原因

 

检查是否捕获了 key-press-event,然后又没有 return TRUE,这将导致发生键盘点击事件时,执行完对应回调函数后信号没有再继续传递,没办法被searchEntry捕获,也就没有办法继续输入文本了。

Continue reading...

Gtk TextView 如何去除白色背景框

Gtk TextView在某些情况下显示的文字会有白色的背景框,显得跟界面格格不入,如下图所示:

上图的源码如下:

Continue reading...

Gtk 创建可自由拖拽、移动的按钮

— Gtk draggable button example c codes

示例代码如下:

命名:dragButton.c

Continue reading...

Gtk获取窗口内光标 | 指针 | 鼠标的绝对和相对坐标,绝对和相对位置

获取指针绝对坐标和窗口内的相对坐标

 

方法一:直接调用函数获得

详情见注释,注意window变量来自 Gtkwidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 代码中没有给出

方法二: 注册回调函数获得

Continue reading...

Gtk窗口在某些情况下无法聚焦窗口的分析与解决办法

(Gtk window focus failed when opened more than one times in one thread)

 

一. 背景:

 

在做Linux取词翻译软件的时候,UI编程使用的是Gtk,翻译界面的逻辑代码被放置于某个线程内,途中会进行多次的创建与销毁,Gtk窗口除了第一次能够成功聚焦,之后就再也无法成功,写了短小的测试用例,发现每次进行进程创建可以保证窗口聚焦。

但是考虑到各个线程中众多的共享数据,另开进程进行数据通信的代价太过于大,主要是进程有独立的地址空间,彼此间通信要借助IPC的方式,而且无论是代码的重构还是之后的调试都将耗费巨大的精力。

 

二. 解决过程:

 

而后开始寻找解决办法,尝试了好几个小时在Gtk内部查找问题,换了或增加了各种各样的窗口聚焦相关代码,仍旧不可行。

接着想到了另一个突破口,平时Alt-tab键可以进行窗口切换,本质就是聚焦窗口的改变,巡着这条路想起xdotool好像有这个功能可以激活特定窗口(亦即聚焦窗口)。

然后在终端尝试了一下,果然,用 xdotool windowactivate <窗口id>可以激活窗口!马上阅读源码,很快找到了相关实现的函数,在里面添加了些log的打印进行进一步定位,或者注释掉一些可能实际起作用的代码后,程序窗口激活功能即刻失效,由此得到几行关键代码:

Continue reading...

记一次Gtk编程遇到问题的解决过程 (GtkSearchEntry绑定新的快捷键,信号发生快捷键)

最近用到GtkSearchEntry的编程,其中一个信号是stop-search,对应绑定的默认快捷键是ESC,一般捕获为退出信号,感觉不顺手,想绑定到Ctrl-C,中途遇到了问题,查看全网没有发现解决方案,但是从StackOverFlow的这篇文章里找到一点灵感 Gtk3 keys bindings in css files。特此记录此问题的解决过程和思路。

查看Gtk开发手册,如下:

The  stop-search signal

The ::stop-search signal is a keybinding signal which gets emitted when the user stops a search via keyboard input.

Applications should connect to it, to implement hiding the search entry in this case.

The default bindings for this signal is Escape.

Parameters

entry the entry on which the signal was emitted
user_data user data set when the signal handler was connected.

Flags: Action

Since: 3.16

通过描述可以看到stop-search是键盘绑定信号,用户输入特定键盘触发后发射出该信号。

点进 keybinding signal ,找到文章开头的一些函数:

void gtk_binding_entry_add_signall ()
GtkBindingSet * gtk_binding_set_new ()
GtkBindingSet * gtk_binding_set_by_class ()
GtkBindingSet * gtk_binding_set_find ()
gboolean gtk_bindings_activate ()
gboolean gtk_bindings_activate_event ()
gboolean gtk_binding_set_activate ()
void gtk_binding_entry_add_signal ()
GTokenType gtk_binding_entry_add_signal_from_string ()
void gtk_binding_entry_skip ()
void gtk_binding_entry_remove ()
void gtk_binding_set_add_path ()

其中看着比较像的是gtk_binding_entry_add_signal (),点进去看函数原型:

gtk_binding_entry_add_signal ()

Override or install a new key binding for  keyval with  modifiers on  binding_set . When the binding is activated,  signal_name will be emitted on the target widget, with  n_args  Varargs used as arguments.

Each argument to the signal must be passed as a pair of varargs: the GType of the argument, followed by the argument value (which must be of the given type). There must be  n_args pairs in total.

 

keyval(键值),modifiers(修饰符),和signal_name(信号名)容易知道,比如我想要绑定到Ctrl-C,那么keyval就是c,modifiers就是control,signal-name就是stop-search,但是写法可能要替换成一些特定的宏,这些问题不大,从gtk的源码中找到规律,keyval一般写成 GDK_KEY_c 这种格式,Control写成 GDK_CONTROL_MASK , signal-name还是原来的字符串不用变。

问题最大的是GtkBindingSet如何获取,它的原型是一个结构体,里面包含很多变量,我们不可能自己定义一个,因为这在Gtk源码中肯定已经定义过了,目的到现在变成了如何获取这个GtkBindingSet。

再细看上面的一些函数,其中有3个返回值都是GtkBindingSet,大概率是从这里入手,通过名称可以排除包含new的函数,因为是获取已有的,而不是new一个新的,剩下两个通过对比确定为如下目标函数:

gtk_binding_set_by_class ()

This function returns the binding set named after the type name of the passed in class structure. New binding sets are created on demand by this function.

Parameters

object_class a valid GObject class

Returns

the binding set corresponding to  object_class .

至于为什么选这个,首先从它的内部传参可以看出,只需要传进一个有效的GObject class 即可。

因此,问题再进一步,变成:如何获取GObject class

到这里,感觉离目标已经越来越接近,但是对于Gtk Class了解不够,且不太懂得该如何获取,其内部机制也不了解。

一个很关键的思路转折出现了,既然GtkSearchEntry是继承自GtkEntry,那么关键突破点不应该只在GtkSearchEntry中找,很有可能在其继承的基类中存在一些我们要的结果。

 

而类名一般与部件widget名相关,即,可能对我们有帮助的类名是GtkSearchEntryClass或者是GtkEntryClass,接着我在Gtk源码根目录输入如下命令:

从输出结果中看到这么一行

Continue reading...

Vim获取特定行作为字符串复制给变量

let headTxt=getline(1) 获取第一行赋值给字符串headTxt

可以将上述逻辑放在一个函数里,绑定到特定键盘,当调用这个函数的时候,自动判断,如果是关于Gtk的C文件,则执行第一个gcc编译操作,否则执行第二个。…

Continue reading...