提供选中区@GTK+ 2.0 中文教程连载

提供选中区

提供选中区要复杂一点。你必须注册当选中区被要求时将调用的处理函数。每处理一对选中区/目标,你就要调用一次下面的函数:

void gtk_selection_add_target (GtkWidget           *widget, 
GdkAtom selection,
GdkAtom target,
guint info);

widgetselectiontarget 标识了这个处理函数要操作的要求。当对选中区的一个要求被接收,"selection_get" 信号将被调用。info 能用来标识回调函数里的指定目标。

回调函数形式如下:

void  "selection_get" (GtkWidget          *widget,
GtkSelectionData *selection_data,
guint info,
guint time);

GtkSelectionData和上面介绍的一样,但这次,我们要负责提供typeformatdatalength 值(format 值在这里很重要-X服务器根据它来确定数据是否要以字节为单位处理。通常它的值为8 - 字符型 -或 32- 整型)。调用下面的函数来设置这些值:

void gtk_selection_data_set( GtkSelectionData *selection_data,
GdkAtom type,
gint format,
guchar *data,
gint length );

这个函数会适当地将数据复制一份这样你就不必为保留这些数据操心了。(不要手工填充GtkSelectionData结构里的值。)

用户做了某个操作后,你可以通过下面的函数声称选中区的所有权。

gboolean gtk_selection_owner_set( GtkWidget *widget,
GdkAtom selection,
guint32 time );

如果其它应用程序要求得到选中区,你将接收到"selection_clear_event"信号。

下面是一个提供选中区的示例,它给开关按钮加了选中区功能。当开关按钮被按下,程序要求得到主选中区。它只支持"STRING"目标(除了 GTK 自身已支持的"TARGETS"等目标)。当这个目标被要求时,一个描叙时间的字符串被返回。

#include <stdlib.h>
#include <gtk/gtk.h>
#include <time.h>

GtkWidget *selection_button;
GtkWidget *selection_widget;

/* 当用户触发选中区时的回调 */
void selection_toggled( GtkWidget *widget,
gint *have_selection )
{
if (GTK_TOGGLE_BUTTON (widget)->active)
{
*have_selection = gtk_selection_owner_set (selection_widget,
GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
/* 如果声称选中区失败,则使按钮返回未选中状态 */
if (!*have_selection)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
}
else
{
if (*have_selection)
{
/* 在设置所有者为NULL来清空选中区前,
* 先检测自己是不是真正的所有者 */
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
*have_selection = FALSE;
}
}
}

/* 当其它应用程序声称选中区时调用 */
gint selection_clear( GtkWidget *widget,
GdkEventSelection *event,
gint *have_selection )
{
*have_selection = FALSE;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (selection_button), FALSE);

return TRUE;
}

/* 将当前时间作为选中区内容提供。 */
void selection_handle( GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time_stamp,
gpointer data )
{
gchar *timestr;
time_t current_time;

current_time = time (NULL);
timestr = asctime (localtime (&current_time));
/* 当我们返回单独一个字符串时,它不必以NULL结尾。
它将被自动完成 */

gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
8, timestr, strlen (timestr));
}

int main( int argc,
char *argv[] )
{
GtkWidget *window;

static int have_selection = FALSE;

gtk_init (&argc, &argv);

/* 创建顶级窗口 */

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Event Box");
gtk_container_set_border_width (GTK_CONTAINER (window), 10);

g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (exit), NULL);

/* 创建一个开关按钮作为选中区 */

selection_widget = gtk_invisible_new ();
selection_button = gtk_toggle_button_new_with_label ("Claim Selection");
gtk_container_add (GTK_CONTAINER (window), selection_button);
gtk_widget_show (selection_button);

g_signal_connect (G_OBJECT (selection_button), "toggled",
G_CALLBACK (selection_toggled), &have_selection);
g_signal_connect (G_OBJECT (selection_widget), "selection_clear_event",
G_CALLBACK (selection_clear), &have_selection);

gtk_selection_add_target (selection_widget,
GDK_SELECTION_PRIMARY,
GDK_SELECTION_TYPE_STRING,
1);
g_signal_connect (G_OBJECT (selection_widget), "selection_get",
G_CALLBACK (selection_handle), &have_selection);

gtk_widget_show (selection_button);
gtk_widget_show (window);

gtk_main ();

return 0;
}

<<< Previous Home Next >>>
获取选中区信息Up 拖放
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值