当前位置: 技术问答>linux和unix
gtk图像显示+滚动条请教
来源: 互联网 发布时间:2015-10-09
本文导语: 最近在进行linux下的glade和gtk编程。遇到一个棘手的问题,特向高手请教! 需求如下: 滚动显示矢量大地图,要求能够缩放。 问题如下: 我构造了一个滚动窗口,在上面加了一个drawingarea,显示一个大矢量图,我的...
最近在进行linux下的glade和gtk编程。遇到一个棘手的问题,特向高手请教!
需求如下:
滚动显示矢量大地图,要求能够缩放。
问题如下:
我构造了一个滚动窗口,在上面加了一个drawingarea,显示一个大矢量图,我的做法是先把矢量图画在pixmap上,然后显示。因为矢量图很大,而滚动窗口的滚动条是根据drawingarea大小判断的(在程序里我用gtk_widget_set_size_request指定大小这样滚动条就能正确显示)。现在我的矢量图要求能够放大,也就是说矢量图可能达到20000*10000那么大,这个时候我用gtk_widget_set_size_request(drawingarea1,20000,10000)系统会报错。我察看了一下内存,在gtk_widget_set_size_request(drawingarea1,2000,1000)时用了7M内存。如果达到5000*4000就用了36M内存。这样内存消耗实在太大。
请教如下:
是不是我的做法有问题,我该怎么正确显示滚动条。
附加代码如下:
callbacks.c:
gboolean
DrawConfigE (GtkWidget *widget,
GdkEventConfigure *event,
gpointer user_data)//config事件
{
ReadRegionListData();
ReadCurveListData();
ReadRoadRiverListData();
if (pixmap)
g_object_unref (pixmap);
pixmap = gdk_pixmap_new (widget->window,widget->allocation.width,widget->allocation.height, -1);
gdk_draw_rectangle (pixmap,widget->style->white_gc,1,0,0,widget->allocation.width,widget->allocation.height);
int i=0,j=0;
GtkPoint * pointsregion;
GdkGC *gc;
GdkColor color;
gc=gdk_gc_new(widget->window);
/*color.red=0xffff;
color.green=0;
color.blue=0;
gdk_color_alloc(gdk_colormap_get_system(),&color);
gdk_gc_set_foreground(gc,&color);
*/
Point3D tempp;
for(;iblack_gc,1,pointsregion,regionList.pRegion[i].pointcount);
color.red=65535;
color.green=0;
color.blue=0;
gdk_color_alloc(gdk_colormap_get_system(),&color);
gdk_gc_set_foreground(gc,&color);
gdk_draw_polygon(pixmap,gc,1,pointsregion,regionList.pRegion[i].pointcount);
}
i=0;
GtkPoint * pointscurve;
for(;iblack_gc,pointscurve ,pcurveList.pPoints[i].pointcount);
}
//-----------------------roadriver------------------------------------
i=0;
GtkPoint * pointleftroad=NULL,*pointrightroad=NULL;
for(;iblack_gc,pointleftroad ,proadList.pRoadRiver[i].leftpointcount);
pointrightroad=malloc(sizeof(GtkPoint)*proadList.pRoadRiver[i].rightpointcount);
j=0;
for(;jstyle->black_gc,pointrightroad ,proadList.pRoadRiver[i].rightpointcount);
}
return FALSE;
}
gboolean
DrawExposeE (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data)//expose事件
{
gdk_draw_drawable (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
//printf("%d,%d,%d,%d,%d,%dn",event->area.x, event->area.y,
// event->area.x, event->area.y,
// event->area.width, event->area.height);
return FALSE;
}
interface.c:
create_window1 (void)
{
GtkWidget *window1;
GtkWidget *scrolledwindow1;
GtkWidget *viewport1;
GtkWidget *drawingarea1;
//GtkAdjustment *adj1, *adj2;
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window1), "window1");
g_signal_connect (G_OBJECT (window1), "delete_event",
G_CALLBACK (quit),
NULL);
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow1),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
gtk_widget_show (scrolledwindow1);
gtk_container_add (GTK_CONTAINER (window1), scrolledwindow1);
viewport1 = gtk_viewport_new (NULL, NULL);
gtk_widget_show (viewport1);
gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
drawingarea1 = gtk_drawing_area_new ();
gtk_widget_show (drawingarea1);
gtk_container_add (GTK_CONTAINER (viewport1), drawingarea1);
gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea1), 600, 400);
//gtk_widget_set_size_request(drawingarea1,400,300);
g_signal_connect ((gpointer) drawingarea1, "configure_event",
G_CALLBACK (DrawConfigE),
NULL);
g_signal_connect ((gpointer) drawingarea1, "expose_event",
G_CALLBACK (DrawExposeE),
NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (window1, window1, "window1");
GLADE_HOOKUP_OBJECT (window1, scrolledwindow1, "scrolledwindow1");
GLADE_HOOKUP_OBJECT (window1, viewport1, "viewport1");
GLADE_HOOKUP_OBJECT (window1, drawingarea1, "drawingarea1");
return window1;
}
需求如下:
滚动显示矢量大地图,要求能够缩放。
问题如下:
我构造了一个滚动窗口,在上面加了一个drawingarea,显示一个大矢量图,我的做法是先把矢量图画在pixmap上,然后显示。因为矢量图很大,而滚动窗口的滚动条是根据drawingarea大小判断的(在程序里我用gtk_widget_set_size_request指定大小这样滚动条就能正确显示)。现在我的矢量图要求能够放大,也就是说矢量图可能达到20000*10000那么大,这个时候我用gtk_widget_set_size_request(drawingarea1,20000,10000)系统会报错。我察看了一下内存,在gtk_widget_set_size_request(drawingarea1,2000,1000)时用了7M内存。如果达到5000*4000就用了36M内存。这样内存消耗实在太大。
请教如下:
是不是我的做法有问题,我该怎么正确显示滚动条。
附加代码如下:
callbacks.c:
gboolean
DrawConfigE (GtkWidget *widget,
GdkEventConfigure *event,
gpointer user_data)//config事件
{
ReadRegionListData();
ReadCurveListData();
ReadRoadRiverListData();
if (pixmap)
g_object_unref (pixmap);
pixmap = gdk_pixmap_new (widget->window,widget->allocation.width,widget->allocation.height, -1);
gdk_draw_rectangle (pixmap,widget->style->white_gc,1,0,0,widget->allocation.width,widget->allocation.height);
int i=0,j=0;
GtkPoint * pointsregion;
GdkGC *gc;
GdkColor color;
gc=gdk_gc_new(widget->window);
/*color.red=0xffff;
color.green=0;
color.blue=0;
gdk_color_alloc(gdk_colormap_get_system(),&color);
gdk_gc_set_foreground(gc,&color);
*/
Point3D tempp;
for(;iblack_gc,1,pointsregion,regionList.pRegion[i].pointcount);
color.red=65535;
color.green=0;
color.blue=0;
gdk_color_alloc(gdk_colormap_get_system(),&color);
gdk_gc_set_foreground(gc,&color);
gdk_draw_polygon(pixmap,gc,1,pointsregion,regionList.pRegion[i].pointcount);
}
i=0;
GtkPoint * pointscurve;
for(;iblack_gc,pointscurve ,pcurveList.pPoints[i].pointcount);
}
//-----------------------roadriver------------------------------------
i=0;
GtkPoint * pointleftroad=NULL,*pointrightroad=NULL;
for(;iblack_gc,pointleftroad ,proadList.pRoadRiver[i].leftpointcount);
pointrightroad=malloc(sizeof(GtkPoint)*proadList.pRoadRiver[i].rightpointcount);
j=0;
for(;jstyle->black_gc,pointrightroad ,proadList.pRoadRiver[i].rightpointcount);
}
return FALSE;
}
gboolean
DrawExposeE (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data)//expose事件
{
gdk_draw_drawable (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
//printf("%d,%d,%d,%d,%d,%dn",event->area.x, event->area.y,
// event->area.x, event->area.y,
// event->area.width, event->area.height);
return FALSE;
}
interface.c:
create_window1 (void)
{
GtkWidget *window1;
GtkWidget *scrolledwindow1;
GtkWidget *viewport1;
GtkWidget *drawingarea1;
//GtkAdjustment *adj1, *adj2;
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window1), "window1");
g_signal_connect (G_OBJECT (window1), "delete_event",
G_CALLBACK (quit),
NULL);
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow1),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
gtk_widget_show (scrolledwindow1);
gtk_container_add (GTK_CONTAINER (window1), scrolledwindow1);
viewport1 = gtk_viewport_new (NULL, NULL);
gtk_widget_show (viewport1);
gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
drawingarea1 = gtk_drawing_area_new ();
gtk_widget_show (drawingarea1);
gtk_container_add (GTK_CONTAINER (viewport1), drawingarea1);
gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea1), 600, 400);
//gtk_widget_set_size_request(drawingarea1,400,300);
g_signal_connect ((gpointer) drawingarea1, "configure_event",
G_CALLBACK (DrawConfigE),
NULL);
g_signal_connect ((gpointer) drawingarea1, "expose_event",
G_CALLBACK (DrawExposeE),
NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (window1, window1, "window1");
GLADE_HOOKUP_OBJECT (window1, scrolledwindow1, "scrolledwindow1");
GLADE_HOOKUP_OBJECT (window1, viewport1, "viewport1");
GLADE_HOOKUP_OBJECT (window1, drawingarea1, "drawingarea1");
return window1;
}
|
你现在用得是scrollwindow吧,用滚动条控件试一下