我需要在一張圖像中選擇一個區域,并在滑鼠的拖動中不斷重畫,按理來說,用gtk_draw_focus()畫了聚集矩形之後,隻要在原來的地方重畫一次,是可以将上次的擦除的,但不知怎麼就是擦不幹淨,于是用了另外一種方法,添加一個gtk_event_box,将将背景設為透明,畫框框都在它裡面完成,這樣在需要擦除時,隻要重畫event_box的一部分矩形即可,而并不影響下面的圖像。
#include <gtk/gtk.h>
GtkWidget *eventbox;
gboolean bleftdown = FALSE;
gint xdown = 0;
gint ydown = 0;
gint oldx =0;
gint oldy = 0;
void Sort(gint *a, gint *b)
{
int c;
if(*a > *b)
{
c = *a; *a = *b; *b = c;
}
}
void RrawRect(GtkWidget* widget,unsigned long R,
unsigned long G, unsigned long B,gint x1, gint y1, gint x2, gint y2)
{
GdkGC *gc;
GdkColormap *cmap;
GdkColor color;
Sort(&x1, &x2);
Sort(&y1, &y2);
cmap = gdk_colormap_get_system();
gc = gdk_gc_new(widget->window);
color.red=R;// 0x00;
color.green = G;// 0xFFFF;
color.blue = B;//0x0;
if (gdk_color_alloc(cmap, &color) == 0)
{
g_error("can't allocate color/n");
}
gdk_gc_set_rgb_fg_color(gc, &color);
gdk_draw_rectangle(widget->window,gc,FALSE,x1, y1, x2-x1, y2-y1);
gdk_gc_destroy(gc);
}
void Redraw(gint x1, gint y1, gint x2, gint y2)
{
GdkRectangle rect;
Sort(&x1, &x2);
Sort(&y1, &y2);
rect.x = x1;
rect.y = y1;
rect.width = x2- x1+1;
rect.height =y2 -y1+1;
gtk_widget_draw(eventbox, &rect);
}
gboolean button_release_event_callback(GtkWidget *widget,
GdkEventButton *event,gpointer user_data)
{
if(event->button == 1 ) // left button
{
if (bleftdown && event->type == GDK_BUTTON_RELEASE)
{
bleftdown = FALSE;
RrawRect(eventbox, 0x0000, 0x0000, 0xFFFF, xdown, ydown,event->x , event->y);
}
}
return FALSE;
}
gboolean button_press_event_callback (GtkWidget *widget,
GdkEventButton *event, gpointer user_data)
{
printf("button press/n");
if(event->button == 1 ) // left button
{
if (event->type == GDK_BUTTON_PRESS)
{
Redraw(xdown, ydown, oldx, oldy);
bleftdown = TRUE;
xdown = event->x;
ydown = event->y;
}
}
return FALSE;
}
gboolean motion_notify_event_callback(GtkWidget *widget,
GdkEventMotion *event, gpointer user_data)
{
// GtkStyle* style;
if (bleftdown)
{
//style = gtk_style_new();
Redraw(xdown, ydown, oldx, oldy);
//gtk_draw_focus(style, eventbox->window, xdown, ydown,oldwidth, oldheight);
RrawRect(eventbox, 0x0000, 0xFFFF, 0x0000, xdown, ydown,event->x , event->y);
oldx = event->x;
oldy = event->y;
}
return FALSE;
}
gint close_application( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
gtk_main_quit();
return(FALSE);
}
int main (int argc, char *argv[])
{
GtkWidget *win;
GtkWidget *fixed;
GtkWidget *image;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf2;
gtk_init (&argc, &argv);
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
gtk_widget_set_usize(win, 500, 400);
gtk_window_set_title (GTK_WINDOW (win), "Drawing Rectangle on Image");
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
gtk_widget_realize (win);
eventbox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (win), eventbox );
gtk_widget_set_usize(eventbox, gdk_pixbuf_get_width(pixbuf)*2, gdk_pixbuf_get_height(pixbuf));
gdk_window_set_cursor(eventbox->window, gdk_cursor_new( GDK_CROSS));
fixed = gtk_fixed_new ();
gtk_container_add (GTK_CONTAINER (eventbox), fixed );
pixbuf = gdk_pixbuf_new_from_file ("/bg.jpg", NULL);
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_fixed_put (GTK_FIXED (fixed), image, 0, 0);
pixbuf2 = gdk_pixbuf_new_from_file ("/fruit.jpg", NULL);
image = gtk_image_new_from_pixbuf (pixbuf2);
gtk_fixed_put (GTK_FIXED (fixed), image, 10, 10);
g_signal_connect (G_OBJECT (win), "delete_event",
G_CALLBACK (close_application), NULL);
gtk_widget_add_events (eventbox, GDK_POINTER_MOTION_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
);
g_signal_connect (eventbox, "button-press-event", G_CALLBACK(button_press_event_callback), NULL);
g_signal_connect (eventbox , "button-release-event", G_CALLBACK(button_release_event_callback), NULL);
g_signal_connect (eventbox , "motion_notify_event", G_CALLBACK(motion_notify_event_callback), NULL);
gtk_widget_show_all(win);
gtk_main ();
return 0;
}