注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

jasy.ice 的小房子

iceplayer gtk linux c

 
 
 

日志

 
 

gtk 文件拖放(转)  

2010-04-17 16:13:49|  分类: GTK |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
如何在GTK+中实现拖放

1.概述

一个支持GTK+拖放的应用程序先要定义和设置能拖放的构件。每个构件都可以是拖放的来源端和/或目标端。注意这些构件必须有一个关联的 X 窗口,用GTK_WIDGET_NO_WINDOW(widget) 检测。

源构件可以发送拖动数据,因此允许用户把东西从它们上面拖出去,同时目标构件能接收拖动数据。拖放的目标端能限制它们接受谁的拖动数据,比如,同一应用程序或任意应用程序(包括它自己)。

发送和接收拖动数据是利用GTK+信号来进行的。投放一个项到一个目的构件需要一个数据请求(源构件使用)和数据接收信号处理函数(目的构件使用)。还可以连接一些附加的信号处理函数,如果你想要知道何时拖动开始(在拖动开始的最初阶段),何时投放成功,以及何时整个拖放过程完成(是否成功)。

当接收到请求时,你的应用程序将需要为源构件提供数据,还包括一个拖动数据请求信号处理函数。而对目的构件将需要一个拖动数据接收信号处理函数。

一个典型的拖放周期将像下面这样:

(1)拖动开始。

(2)拖动数据请求(当投放发生)。

(3)拖动数据被接收(可能在同一个应用程序内部或不同应用程序之间)。

(4)拖动数据被删除(如果拖动是移动)。

(5)拖放过程完成。

在它们之间也有一些次要的步骤,但这些我们等下再作详细介绍。

2.属性

拖动数据有下面的这些属性:

(1)拖动行为类型(比如GDK_ACTION_COPY, GDK_ACTION_MOVE)。

(2)客户端指定的任意拖放类型(一个名称和数字组成的对)。

(3)发送和接收的数据格式类型。

拖动行为的意义很明显,它们指定构件是否能以指定的行为来拖动,比如GDK_ACTION_COPY 和/或GDK_ACTION_MOVE。GDK_ACTION_COPY将是一个典型的拖放,它的源数据并不会被删除,而GDK_ACTION_MOVE 将和GDK_ACTION_COPY一样,只是“建议”在接收信号处理函数调用之后将源数据删除掉。还有一些附加的拖动行为包括 GDK_ACTION_LINK等,当你对拖放的使用达到更高水平时,你可能会使用到。

客户端指定的任意拖放类型要更加灵活些,因为你的程序将明确地定义和检测它。你需要指定一个名称和/或数字以设置目的构件能接收的特定拖放类型。用一个名称要可靠些,因为其它应用程序可能也正好用了同样的数字来区别它的完全不同的类型。

发送和接收的数据格式类型(selection target)只在请求和接收数据处理函数中使用。术语selection target有些容易令人误解。它应该是一个适合在 GTK+ 选中区(剪切/复制和粘贴)中使用的术语。selection target实际是指被发送和接收的数据的格式类型(比如GdkAtom, integer, 或string)。你的请求数据处理函数必须指定它发送出去的数据的类型(selection target),同时接收数据处理函数要处理接收到的数据的类型(selection target)。

3.函数

(1)设置源构件

gtk_drag_source_set()函数指定一套在构件上拖动操作时的目标类型。

void gtk_drag_source_set( GtkWidget *widget,

GdkModifierType start_button_mask,

const GtkTargetEntry *targets,

gint n_targets,

GdkDragAction actions );

这些参数的作用如下:

widget:指定拖动源构件

start_button_mask:指定能引发拖动操作的鼠标按键的位掩码(bitmask),比如

GDK_BUTTON1_MASK

targets:指定一个此拖动支持的目标数据类型的表格

n_targets:指定上面的目标的数量

actions:指定从这个窗口进行拖动时可能的行为的位掩码

targets:参数是一个由下面的结构组成的数组:

struct GtkTargetEntry {

gchar *target;

guint flags;

guint info;

};

这一结构指定一个代表拖动类型的字符串,可选的标记和应用程序指派的整数标识

符。

如果一个构件不必再担当拖放操作的源,用gtk_drag_source_unset()函数可以删除一套拖放目标类型。

void gtk_drag_source_unset( GtkWidget *widget );

(2)源构件上的信号

在一个拖放操作中源构件将被发送下面的这些信号。

drag_begin void (*drag_begin)(GtkWidget *widget, GdkDragContext *dc,

gpointer data)

drag_motion gboolean (*drag_motion)(GtkWidget *widget, GdkDragContext

*dc, gint x, gint y, guint t, gpointer data)

drag_data_get void (*drag_data_get)(GtkWidget *widget, GdkDragContext

*dc, GtkSelectionData *selection_data, guint info, guint t, gpointer

data)

drag_data_delete void (*drag_data_delete)(GtkWidget *widget,

GdkDragContext *dc, gpointer data)

drag_drop gboolean (*drag_drop)(GtkWidget *widget, GdkDragContext *dc,

gint x, gint y, guint t, gpointer data)

drag_end void (*drag_end)(GtkWidget *widget, GdkDragContext *dc,

gpointer data)

(3)设置目的构件

gtk_drag_dest_set()指定这个构件可以接收拖动并指定它能接收的拖动的类型。

gtk_drag_dest_unset()指定构件不再能接收拖动了。

void gtk_drag_dest_set( GtkWidget *widget,

GtkDestDefaults flags,

const GtkTargetEntry *targets,

gint n_targets,

GdkDragAction actions );

void gtk_drag_dest_unset( GtkWidget *widget );

(4)目的构件上的信号

在一个拖放操作中目的构件将被发送下面的这些信号。

drag_data_received void (*drag_data_received)(GtkWidget *widget,

GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,

guint info, guint t, gpointer data)
  评论这张
 
阅读(633)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->