求助:如何解决子widget刷新覆盖父widget中内容?
我想实现拖动GtkPaned控件中的手柄不进行实时更新,而是有一条虚线表明拖动位置,鼠标弹起时再更新的效果,现在大部分问题都解决了,但是在paned中加入滚动窗口控件显示图片时,图片区域绘制的虚线被刷掉了,应该是子widget刷新时覆盖了父widget的内容,不知道怎么解决!以下是代码:
#include <stdlib.h>
#include <gtk/gtk.h>
gboolean bleftdown = FALSE;
gint oldx = 0;
gint oldy = 0;
void Sort(gint *a, gint *b)
{
int c = 0;
if(*a > *b)
{
c= *a;
*a = *b;
*b = c;
}
return;
}
void RrawRect(GtkWidget* widget,unsigned long R,unsigned long G,
unsigned long B,gint x1, gint y1, gint x2, gint y2)
{
GdkColor color;
GdkGCValues vals;
GdkGC *gc = NULL;
GdkColormap *cmap = NULL;
static gint8 dash_list[] = {1,1};
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;
vals.foreground = color;
vals.line_style = GDK_LINE_ON_OFF_DASH;
gdk_gc_set_values(gc, &vals, GDK_GC_FOREGROUND|GDK_GC_LINE_STYLE);
gdk_gc_set_dashes(gc, 0, dash_list, sizeof(dash_list));
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);
return;
}
voidRedraw(GtkWidget *widget, 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(widget, &rect);
return;
}
gbooleanbutton_release(GtkWidget *widget, GdkEventButton *event,gpointer user_data)
{
if(event->button == 1 ) // left button
{
if (bleftdown && event->type == GDK_BUTTON_RELEASE)
{
bleftdown =FALSE;
RrawRect(widget, 0x400F, 0x400F, 0x400F,
oldx , widget->allocation.y,
oldx+4 , widget->allocation.y + widget->allocation.height-1);
int x = 0, y = 0;
gtk_widget_get_pointer(widget, &x, &y);
gtk_paned_set_position(GTK_PANED(widget),x);
}
}
return FALSE;
}
gbooleanbutton_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
if(event->button == 1 ) // left button
{
if (event->type == GDK_BUTTON_PRESS)
{
int x = 0, y = 0;
gtk_widget_get_pointer(widget, &x, &y);
RrawRect(widget,0x400F, 0x400F, 0x400F,
x , widget->allocation.y,
x+4 , widget->allocation.y + widget->allocation.height-1);
Redraw(widget,
oldx, widget->allocation.y,
oldx+4, widget->allocation.y + widget->allocation.height-1);
bleftdown =TRUE;
oldx = x;
oldy = y;
}
}
return TRUE;
}
gbooleanmotion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
{
if (bleftdown)
{
printf("dragging\n");
int x = 0, y = 0;
gtk_widget_get_pointer(widget, &x, &y);
Redraw(widget,oldx, widget->allocation.y, oldx+4,
widget->allocation.y + widget->allocation.height-1);
RrawRect(widget,0x400F, 0x400F, 0x400F,
x, widget->allocation.y,
x+4 , widget->allocation.y + widget->allocation.height-1);
oldx = x ;
oldy = event->y;
}
return TRUE;
}
gboolean expose_event(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
{
if (bleftdown)
{
int x = 0, y = 0;
gtk_widget_get_pointer(widget, &x, &y);
Redraw(widget,oldx, widget->allocation.y, oldx+4,
widget->allocation.y + widget->allocation.height-1);
RrawRect(widget,0x400F, 0x400F, 0x400F,
x, widget->allocation.y,
x+4 , widget->allocation.y + widget->allocation.height-1);
oldx = x ;
}
return FALSE;
}
gint close_application( GtkWidget *widget,
GdkEvent*event,
gpointer data )
{
gtk_main_quit();
return(FALSE);
}
int main (int argc, char *argv[])
{
GtkWidget *win = NULL;
GtkWidget *label = NULL;
GtkWidget *image = NULL;
GdkPixbuf *pixbuf = NULL;
GtkWidget *paned = NULL;
GtkWidget *scrollw = NULL;
GtkWidget *fixed = NULL;
GtkWidget *eventbox = NULL;
/* Initialize GTK+ */
gtk_init (&argc, &argv);
/* Create the main window */
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);
pixbuf = gdk_pixbuf_new_from_file ("/home/allon/pics/cairo.jpg", NULL);
image = gtk_image_new_from_pixbuf (pixbuf);
eventbox = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(eventbox), image);
fixed = gtk_fixed_new();
scrollw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollw), eventbox);
gtk_widget_add_events(scrollw, GDK_EXPOSURE_MASK);
label = gtk_label_new("add to paned");
gtk_rc_parse_string("style 'my_style' {\n"
"GtkPaned::handle-size = 6\n"
" }\n"
"widget '*' style 'my_style'");
paned = gtk_hpaned_new();
gtk_paned_add1(GTK_PANED(paned), label);
gtk_paned_add2(GTK_PANED(paned), scrollw);
g_signal_connect (G_OBJECT (win), "delete_event",
G_CALLBACK (close_application), NULL);
gtk_widget_add_events(paned,
GDK_POINTER_MOTION_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_POINTER_MOTION_HINT_MASK);
g_signal_connect (eventbox , "motion-notify-event", G_CALLBACK(expose_event), NULL);
g_signal_connect (paned , "button-press-event", G_CALLBACK(button_press), NULL);
g_signal_connect (paned , "button-release-event", G_CALLBACK(button_release), NULL);
g_signal_connect (paned , "motion-notify-event", G_CALLBACK(motion_notify), NULL);
gtk_container_add (GTK_CONTAINER (win), paned );
gtk_widget_show_all(win);
gtk_main ();
return 0;
}
事实证明,并不是子控件刷新覆盖了父控件绘制的图形,而是对于一些控件,比如Layout、Treeview等,需要在其bin_window上绘制图形,而不是在其window上绘制图形。
页:
[1]