GTK+学习笔记(二)

你将学到什么

如何使用剪切板

剪切板简介

GtkClipboard对象代表不同进程或同一进程不同构件的剪切板数据。标识每个剪切板的名字被编码成GdkAtom(可以通过gdk_atom_intern()和gdk_atom_name()获取编码前的名字)。默认的剪切板对应名为CLIPBOARDGdkAtom;另一个在XServer系统中经常使用的剪切板名为PRIMARY
为了能让剪切板能同时处理多种格式的数据,剪切板提供了回调函数的机制来处理实际数据。当你设置剪切板数据的时候,你可以使用gtk_clipboard_set_text()直接设置数据,或者使用gtk_clipboard_set_with_data()gtk_clipboard_set_with_owner()提供一个当剪切板的数据被使用时,才设置剪切板数据的回调函数。如果是构件提供剪切板内容,就用gtk_clipboard_set_with_owner(),如果拷贝的是基础类型数据,比如字符串,就用gtk_clipboard_set_with_data()
请求剪切板数据可以是异步的,在同一进程中可以直接调用函数获取剪切板数据,但是从其他进程获取剪切板的数据可能要花费点时间。为了避免阻塞进程,gtk_clipboard_request_contents()提供了一个回调函数来接收数据。如果你不想使用回调方式,你也可以使用gtk_clipboard_wait_for_contents()阻塞等待数据的到来。

获取剪切板

// 获取一种类型的剪切板
GtkClipboard *gtk_clipboard_get (GdkAtom selection);

获取剪切板的数据

// 阻塞等待剪切板数据
gchar *gtk_clipboard_wait_for_text (GtkClipboard *clipboard);
// 异步获取剪切板数据
void gtk_clipboard_request_text (GtkClipboard *clipboard, GtkClipboardTextReceivedFunc callback, gpointer user_data);

右键粘贴简单实现

项目地址

#include <gtk/gtk.h>

gint on_button_press_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    g_return_val_if_fail(widget != NULL, FALSE);
    g_return_val_if_fail(GTK_IS_MENU(data), FALSE);
    g_return_val_if_fail(event != NULL, FALSE);

    if (event->type == GDK_BUTTON_PRESS)
    {
        GdkEventButton *mouse = (GdkEventButton *) event;
        if (mouse->button == GDK_BUTTON_SECONDARY)
        {
            gtk_widget_show_all(GTK_WIDGET(data));
            // gtk_menu_popup_at_pointer(GTK_MENU(data), event);
            gtk_menu_popup(GTK_MENU(data), NULL, NULL, NULL, NULL, mouse->button, mouse->time);
            return TRUE;
        }
    }
    return FALSE;
}

void on_paste(GtkMenuItem *menuitem, gpointer data)
{
    GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
    gchar *text = gtk_clipboard_wait_for_text(clip);
    gtk_label_set_text(GTK_LABEL(data), text);
}

int main( int argc, char *argv[])
{
    GtkWidget *window;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 250);
    GtkWidget *label = gtk_label_new("test");
    gtk_container_add(GTK_CONTAINER(window), label);

    GtkWidget *menu = gtk_menu_new();
    GtkWidget *pasteMi = gtk_menu_item_new_with_label("Paste");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), pasteMi);
    g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(on_button_press_event), menu);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(G_OBJECT(pasteMi), "activate", G_CALLBACK(on_paste), label);
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}
posted @ 2018-05-25 11:26  银魔术师  阅读(1338)  评论(0编辑  收藏  举报