Chinaunix首页 | 论坛 | 博客
  • 博客访问: 192245
  • 博文数量: 111
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 1240
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-07 07:46
文章分类

全部博文(111)

文章存档

2015年(2)

2014年(1)

2011年(1)

2010年(7)

2009年(100)

我的朋友

分类: LINUX

2009-08-19 07:41:29


转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静

GtkClipboard 功能强大,但其风格与Win32上剪贴板相差极大,对于刚接触GTK+编程的程序员来说,特别是已经习惯于Win32剪贴板用法的程序员来说,易用性不是 太好。这方面的文档也比较少,最近学习使用GTK+的剪贴板,竟花了好几个小时才学会,这里做个笔记,供大家参考。

基本用法:

通过剪贴板操作内置的数据类型非常方便,但内置的类型比较少,只有文本和图片等等。

1. 拷贝。拷贝文本非常简单,先获得一个clipboard对象,然后调用gtk_clipboard_set_text。

void
on_button_copy_clicked(GtkButton *button, gpointer user_data)
{
 
GtkClipboard* clipboard = gtk_widget_get_clipboard(button, GDK_SELECTION_CLIPBOARD);
 
const char* text = gtk_entry_get_text(GTK_ENTRY(lookup_widget(GTK_WIDGET(button), "entry1")));
 
gtk_clipboard_set_text(clipboard, text, strlen(text));
 
return;
}

2. 粘贴。拷贝文本稍微麻烦一点,要实现一个回调函数。调用gtk_clipboard_request_text函数后,clipboard回调这个函数,并把数据传递过来。

static void on_paste_text(GtkClipboard *clipboard, const gchar *text, gpointer data)
{
 
gtk_entry_set_text(GTK_ENTRY(lookup_widget(GTK_WIDGET(data), "entry2")), text);
 
return;
 
}
 
void
on_button_paste_clicked (GtkButton *button, gpointer user_data)
{
 
GtkClipboard* clipboard = gtk_widget_get_clipboard(button, GDK_SELECTION_CLIPBOARD);
 
gtk_clipboard_request_text(clipboard, on_paste_text, button);
 
return;
}

高级用法:

如要使用自定义的数据类型,就有点麻烦了。下面我们用一个简单示例,演示一下支持HTML类型的操作。当然,HTML也是文本,你可以以操作文本的方式操作HTML,这里选择HTML只是作为演示目的,没有太大的实用价值。

1. 对外接口。我们选择与文本操作类似的函数接口。

typedef void (* GtkClipboardHtmlReceivedFunc)(GtkClipboard     *clipboard,
const gchar *html,
gpointer data);
 
void gtk_clipboard_set_html(GtkClipboard *clipboard,
const gchar *html,
gint len);
 
void gtk_clipboard_request_html(GtkClipboard *clipboard,
GtkClipboardHtmlReceivedFunc callback,
gpointer user_data);

2. 实现拷贝。

剪贴板中的数据类型是用atom表示的,atom实际上就是字符串的ID,它与字符串一一对应,通常在多个进程中都保持这种对应关系(依赖于具体的平台),我们的数据类型为atom_html,它是通过gdk_atom_intern 获得的。

实现拷贝操作时,要实现两个回调函数: GtkClipboardGetFunc和GtkClipboardClearFunc。前者用来检查和转换数据,然后放到剪贴板中。后者用来清除数据。

static GdkAtom atom_html =  0;
static void
html_get_func (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
guint info,
gpointer data)
{
 
char* str = (char*)data;
 
int len = strlen(str);
 
if (selection_data->target == atom_html)
{
 
gtk_selection_data_set (selection_data,
 
atom_html,
 
8, (guchar *)str, len);
 
}
 
return ;
}
 
static void
html_clear_func (GtkClipboard *clipboard,
gpointer data)
{
 
g_free (data);
 
return;
}
 
void gtk_clipboard_set_html(GtkClipboard *clipboard,
const gchar *html,
gint len)
{
 
GtkTargetEntry *targets = NULL;
 
targets = g_new0 (GtkTargetEntry, 1);
 
targets[0].target = STR_ATOM_HTML;
 
atom_html = gdk_atom_intern (STR_ATOM_HTML, FALSE);
 
gtk_clipboard_set_with_data (clipboard,
 
targets, 1,
 
html_get_func, html_clear_func,
 
g_strndup (html, len));
 
g_free(targets );
 
return;
}

3. 实现粘贴。

实现粘贴操作时,要实现一个回调函数GtkClipboardReceivedFunc,它主要是检查剪贴板中的数据类型,如果正确,就调用用户设置的回调函数,把数据传递过去。

struct _RequestHtmlInfo
{
 
GtkClipboardHtmlReceivedFunc callback;
 
gpointer user_data;
 
};
 
typedef struct _RequestHtmlInfo RequestHtmlInfo;
static void
request_html_received_func (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
gpointer data)
{
 
RequestHtmlInfo *info = data;
 
gchar *result = NULL;
 
if (selection_data->target == atom_html)
{
 
result = g_strdup(selection_data->data);
 
info->callback (clipboard, result, info->user_data);
 
g_free (info);
 
g_free (result);
 
}
 
return;
}
 
void gtk_clipboard_request_html(GtkClipboard *clipboard,
GtkClipboardHtmlReceivedFunc callback,
gpointer user_data)
{
 
RequestHtmlInfo *info;
 
atom_html = gdk_atom_intern (STR_ATOM_HTML, FALSE);
 
g_return_if_fail (clipboard != NULL);
 
g_return_if_fail (callback != NULL);
 
info = g_new (RequestHtmlInfo, 1);
 
info->callback = callback;
 
info->user_data = user_data;
 
gtk_clipboard_request_contents (clipboard, atom_html, request_html_received_func,
info);
 
return;
 
}

由于我们支持HTML类型操作与文本类型操作的接口类似,其用法与基本用法几乎一样,这里不再多说。

阅读(832) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~