学习使用GTK+ 5.GTK+常用物件及API(文本)

400 篇文章 3 订阅
147 篇文章 0 订阅

学习使用GTK+ 5.GTK+常用物件及API(文本)

学习使用GTK+ 系列的第 6 篇 (本系列共6篇)

这一部分内容介绍有关GTK+常用文本类物件的一些函数。如果对内容有疑问,请在下方留言,谢谢!

GTK+的文本

显示文字和控制文本框自然是界面重头戏,基本每个窗口都离不开这样的物件。GTK+中和文本有关的物件主要有:文本标签(GtkLabel,以下简 称“文本”),输入框(GtkEntry),可编辑多行文本(GtkTextView,以下简称“多行文本”),调节按钮 (GtkSpinButton)。各物件有自己的优点。

  • 文本:简单地显示一些文字,使用非常方便,一般用于显示界面上最普通的文字。
  • 输入框:用于让用户输入一行文字,使用方便。
  • 多行文本:用于让用户输入多行文字,或显示一段非常长的文字,可配合滚动区(GtkScrolledWindow)使用来达到很好的显示效果,也可为部分文字设置样式。它的缺陷在于使用繁琐。
  • 调节按钮:用于输入数字,在控制数字输入方面的功能非常强大,其右侧有上下调节数字大小的按钮。

具体使用哪个物件需要根据实际情况决定。

访问文本、输入框

对文本类物件的操作基本相似。对这些物件的动态访问基本归结为以下两种——读取所包含的文字信息(读)、设置所包含的文字内容(写)。其他的设置基本不需要动态改变,初始时在Glade中设置好即可(如果真的需要修改,自己去看参考吧)。

下面这些函数用于对文本、输入框的读写,函数名字都很好记。

//写入文本内容

void gtk_label_set_text( GtkLabel * label, const gchar * str) ;
//读取文本内容
const gchar* gtk_label_get_text( GtkLabel * label) ;
//写入输入框内容
void gtk_entry_set_text( GtkEntry * entry, const gchar * text) ;
//读取输入框内容
const gchar* gtk_entry_get_text( GtkEntry * entry) ;

使用调节按钮

调节按钮是用于操作数字的,因而可以直接向其中写入或者读出实数或整数。

//设置调节按钮的数值

void gtk_spin_button_set_value ( GtkSpinButton * spin_button, gdouble value) ;
//读出调节按钮的数值
gdouble gtk_spin_button_get_value ( GtkSpinButton * spin_button) ;
gint gtk_spin_button_get_value_as_int( GtkSpinButton * spin_button) ;

做个实例吧。本系列第三部分做了一个计算器雏形,下面来稍稍完善一下。

计算器的上方有一个名为SAns的调节按钮,下面增加一个功能:当调节按钮的值的绝对值过大(大于等于常数CAL_ABS_MAX)时,弹出错误提示窗口。

每个调节按钮对应一个GtkAdjustment,首先应为调节按钮添加一个GtkAdjustment。在Glade中,点“常规”的“调整部件”右侧的“…”,弹出窗口中点“New”。

此时上方的物件选择栏末尾中会出现一个对象adjustment1,可以更改它的属性,即调节按钮的最值、步长等。

然后为SAns的信号value-changed添加操作句柄“on_SAns_value_changed”,然后在程序中添加相应回调函数。

回到程序中,在初始化时,用gtk_spin_button_set_range()修改调节按钮取值范围为 [-CAL_ABS_MAX,CAL_ABS_MAX],再编写回调函数on_SAns_value_changed(),顺便用上上一部分写的函数 gtk_show_error()。完整代码如下。

#include <gtk/gtk.h>

 
#define CAL_ABS_MAX 1e9
 
#define w_(builder,type,name) name=GTK_##type(gtk_builder_get_object(builder,#name))
 
GtkWindow * WMain;
GtkSpinButton * SAns;
 
//显示一个错误提示窗口
void gtk_show_error( gpointer window, const gchar* message, const gchar* title)
{
GtkWidget * dialog;
dialog = gtk_message_dialog_new_with_markup( window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
message) ;
gtk_window_set_title( GTK_WINDOW( dialog) , title) ;
gtk_dialog_run( GTK_DIALOG( dialog) ) ;
gtk_widget_destroy( dialog) ;
}
 
G_MODULE_EXPORT void on_SAns_value_changed( GtkObject* widget, gpointer user_data)
{
//gdouble在Windows下等价于double
gdouble d;
//读取调节按钮的值
d= gtk_spin_button_get_value( SAns) ;
//判断是否需要显示错误提示窗口
if ( d>= CAL_ABS_MAX)
{
gtk_show_error( WMain, "Too Large" , "Error!" ) ;
//设置调节按钮值为零
gtk_spin_button_set_value( SAns, 0 ) ;
}
else if ( - d>= CAL_ABS_MAX)
{
gtk_show_error( WMain, "Too Small" , "Error!" ) ;
//设置调节按钮值为零
gtk_spin_button_set_value( SAns, 0 ) ;
}
}
 
G_MODULE_EXPORT void on_WMain_destroy( GtkObject* widget, gpointer user_data)
{
gtk_main_quit( ) ;
}
 
GtkBuilder* gtk_load_glade( gchar* filename)
{
GtkBuilder * gb;
 
gb= gtk_builder_new( ) ;
if ( ! gtk_builder_add_from_file( gb, filename, NULL) ) return NULL;
gtk_builder_connect_signals( gb, NULL) ;
 
return gb;
}
 
void cal_get_widgets( GtkBuilder* gb)
{
w_( gb, WINDOW, WMain) ;
w_( gb, SPIN_BUTTON, SAns) ;
}
 
void cal_widget_init( )
{
//初始化,设置调节按钮取值范围,数值超出此范围时自动调整为边界值。
gtk_spin_button_set_range( SAns,- CAL_ABS_MAX, CAL_ABS_MAX) ;
 
gtk_widget_show_all( GTK_WIDGET( WMain) ) ;
}
 
int main( int argc, char * argv[ ] )
{
GtkBuilder * gb;
 
gtk_init( & argc,& argv) ;
 
gb= gtk_load_glade( "gtk-cal.glade" ) ;
if ( gb== NULL) return - 1 ;
cal_get_widgets( gb) ;
cal_widget_init( ) ;
 
gtk_main( ) ;
 
return 0 ;
}

在以后的内容中,这个计算器将被逐渐完善。

访问多行文本

多行文本的使用比较复杂,涉及几个其他对象的使用。一个多行文本的内容储存在一个缓冲区GtkTextBuffer中,这个缓冲区需要用迭代器GtkTextIter访问、用GtkTextMark标记,文字样式用GtkTextTag设置。

看起来真的有些复杂。不过最基本的应用还是读、写。下面给出三个函数,可以直接读写多行文本。这几个函数基本够用了。

//读取多行文本中的文字内容

gchar* gtk_text_view_get( GtkTextView * text_view)
{
GtkTextBuffer * tb;
GtkTextIter st, stp;
 
tb= gtk_text_view_get_buffer( text_view) ; //获取对应的GtkTextBuffer
gtk_text_buffer_get_start_iter( tb,& st) ; //获得起始点
gtk_text_buffer_get_end_iter( tb,& stp) ; //获得结束点
return gtk_text_buffer_get_text( tb,& st,& stp, FALSE) ; //获得两点间所有字符
}
//在多行文本末尾追加文字,文字样式包含在text_tag中,如果不需要指定样式,text_tag设为NULL
void gtk_text_view_append_with_tag( GtkTextView* text_view, const gchar* text, GtkTextTag* text_tag)
{
GtkTextBuffer * tb;
GtkTextIter stp;
 
tb= gtk_text_view_get_buffer( text_view) ;
gtk_text_buffer_get_end_iter( tb,& stp) ;
gtk_text_buffer_insert_with_tags( tb,& stp, text, strlen( text) , text_tag, NULL) ; //在结束点处追加字符
gtk_text_buffer_get_end_iter( tb,& stp) ;
gtk_text_view_scroll_to_iter( text_view,& stp, 0 , FALSE, 0 , 0 ) ; //将光标置于结束点
}
//清空多行文本
void gtk_text_view_clear( GtkTextView * text_view)
{
gtk_text_buffer_set_text( gtk_text_view_get_buffer( text_view) , "" , 0 ) ; //设置文本内容为空
}

此外,样式可以这样新建:

gtk_text_buffer_create_tag(
gtk_text_view_get_buffer(
text_view)
,
 tag_name,
 property1,
 value1,
 property2,
 value2,
 ... ,
 NULL)
;

text_view是多行文本名字;tag_name是一个字符串,值不能和别的样式相同;property1,2,3,…各属性名字(字符串形式),可用的属性参见http://library.gnome.org/devel/gtk/unstable/GtkTextTag.html 中的Property栏;value1,2,3,…各属性对应的值(字符串形式)。

如果以上的方法不够用,只好查参考了。

小提醒:多行文本一般都需要放在滚动区(GtkScrolledWindow)里面。

处理UTF-8字符串

要注意的问题是,GTK+内部使用UTF-8编码。在处理非ASCII编码的字符串时,切不可使用C语言string.h里的函数。在UTF-8 中,字符含义比较复杂。还好,GLib中提供了很多用于处理多种编码字符串的函数,下面介绍一些用于处理UTF-8字符串的函数。

http://library.gnome.org/devel/glib/stable/glib-Unicode-Manipulation.html 中介绍了很多有关UTF-8字符串的实用函数。这些函数命名与string.h里的常用函数相近,只是多了前缀g_utf8_,表示是专门用来处理UTF-8字符串的。介绍几个吧。

  • g_utf8_strlen():统计UTF-8字符串中的字符数。在UTF-8编码中,不同语言的字符所占用的字节数不同(例如一个中文字符占3个字节),因而UTF-8所包含的字符数小于等于它的字节数,并且没有一个固定的关系。这个函数还是很常用且重要的。
  • g_utf8_find_prev_char():已知某个字符的首地址,查找它前一个字符的首地址。因为不同语言的字符所占用的字节数不同,两个紧邻字符地址之差可能大于1。
  • g_utf8_find_next_char():已知某个字符的首地址,查找它后一个字符的首地址。
  • g_utf8_strncpy():拷贝出字符串的前n个字符(而不是前n个字节)。
  • g_utf8_strchr():找到一个给定的字符最左端出现的位置。UTF-8字符串中字符是gunichar型,相当于一个32位无符号整数,对于非ASCII字符,其值大于127。
  • g_utf8_collate():比较两个字符串的大小(以字典序靠前的为小)。这个函数的强大之处在于,它可以根据所处的语言环境来判断两个字符串的字典顺序,可以比较任何语言的UTF-8字符串!

http://library.gnome.org/devel/glib/stable/glib-String-Utility-Functions.html 列 出了一些跨字符集的实用函数,适用于任何字符集。其中有一部分常常能用上,比如g_snprintf()和g_strdup_printf(),它们的功 能与C语言sprintf类似,都是把一串格式输出写进字符串里(常用于数字和字符混合输出到字符串里),但g_snprintf()和 g_strdup_printf()更安全。g_snprintf()需要指定目的字符串长度,避免输出越界;g_strdup_printf()则在函 数内部自行申请足够的空间存放目的字符串(注意它返回的字符串废弃之后需要用g_free()释放空间)。

http://library.gnome.org/devel/glib/stable/glib-Character-Set-Conversion.html 有一些字符集转换的函数,有些需要字符集转换的场合会用得上(比如文件名可能不是UTF-8编码,有时需要转换)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值