GTK+中文社区(gtk.awaysoft.com)

 找回密码
 马上加入

QQ登录

只需一步,快速开始

查看: 3886|回复: 0

【转】GTK+剪贴板使用实例

[复制链接]
  • TA的每日心情
    奋斗
    2021-11-19 13:15
  • 签到天数: 20 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2009-4-25 16:09:32 | 显示全部楼层 |阅读模式
    转载时请注明出处和作者联系方式
    文章出处:http://www.limodev.cn/blog
    作者联系方式:李先静 <xianjimli at hotmail dot com>
    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类型操作与文本类型操作的接口类似,其用法与基本用法几乎一样,这里不再多说。
    *滑块验证:
    您需要登录后才可以回帖 登录 | 马上加入

    本版积分规则

    申请友链|Archiver|小黑屋|手机版|GTK+中文社区 ( 粤ICP备13080851号 )

    我要啦免费统计

    GMT+8, 2024-4-28 05:58 , Processed in 0.026531 second(s), 7 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表