如何清除gtk、goocanvas表面?

How to clear gtk, goocanvas surface?

我正在使用 goocanvasGTK 框架上绘制一个简单图表,图表尺寸基于相同 window 上的值。当用户使用微调按钮更改界面上的值时,图表应实时更改其尺寸。

我成功地在 gtk window->hbox->frame 上渲染了初始图表。

问题出在更改值时。它在绘图之上重绘。

那么有任何 "clear" 功能可用于 goo canvas 吗?

或者有什么其他方法可以达到预期的效果吗?

编辑:

当前代码:

/*
 * Compile me with:
 * gcc -o dia dia.c `pkg-config --libs --cflags gtk+-2.0 goocanvas` -rdynamic -I./headers/ -lm
 * 
 */

#include <stdio.h>
#include <gtk/gtk.h>
#include <goocanvas.h>

/*Common structs and varaibles*/

struct dia_struct
{
    gdouble diam;
    const gchar *tbp, *thtp, *wt;
};

struct dia_struct set_dia; /* intitializing the structure */

/* Goo canvas items */
GooCanvasItem *root, *path, *path2;

GtkWidget  *canvas;

/*
 * Function:  ofdra
 * --------------------
 * This is the main function to draw the diagram on screen
 *  
 *  returns: none
 */
void ofdra (double diam)
{ 
    double dfactor = diam*50;

    path = NULL;
    path2 = NULL;

    double x = (465-dfactor)/2;
    double y = 465-x;

    char buf[100];
    char buf2[100];
    sprintf(buf, "M 0 %f L 1000 %f", x, x);
    sprintf(buf2, "M 0 %f L 1000 %f", y, y);

    path = goo_canvas_path_new (root, buf, "stroke-color", "red", NULL);
    path2 = goo_canvas_path_new (root, buf2, "stroke-color", "red", NULL);

    /*goo_canvas_item_update (path, TRUE, );*/
    /*goo_canvas_item_update (path2);*/

}

/*
 * Function:  ofruta
 * --------------------
 * This is the main function to run when in a user changed a value.
 *
 *  glade_wdgets: widget-object
 *  pObList: array of objects to go through
 *  
 *  returns: none
 */
void ofruta (GtkWidget *glade_wdgets, gpointer *pObList)
{
    /* common varaibles needed */

    struct dia_struct dia; /* intitializing the structure */

    /* getters */
    dia.diam = gtk_spin_button_get_value (GTK_SPIN_BUTTON(pObList[0])); /* diameter reading */

    set_diamond.diam = diamond.diam;

    gtk_spin_button_set_value(GTK_SPIN_BUTTON(pObList[0]), set_diamond.diam);

    /* Loads all dynamically generated diagram drawing */
    ofdra(set_diamond.diam);
}

//===========================================================================
/*
 * main
 *
 * Program begins here
 */
int main( int argc, char **argv )
{
    GtkBuilder *builder;
    GtkWidget  *window;
    GError     *error = NULL;
    GtkButton *button;
    GtkLabel *label;

    cairo_surface_t *surface;

    /* Init GTK+ */
    gtk_init( &argc, &argv );

    /* Create new GtkBuilder object */
    builder = gtk_builder_new();
    /* Load UI from file. If error occurs, report it and quit application.
     * Replace "tut.glade" with your saved project. */
    if( ! gtk_builder_add_from_file( builder, "dia_glade.glade", &error ) )
    {
        g_warning( "%s", error->message );
        g_free( error );
        return( 1 );
    }

    /* Get main window pointer from UI */
    window = GTK_WIDGET( gtk_builder_get_object( builder, "window1" ) );

    gpointer spinners[] = { gtk_builder_get_object( builder, "diam" )};

    /* Connect signals */
    gtk_builder_connect_signals( builder, spinners );

    g_signal_connect(G_OBJECT(window), "delete-event", (GCallback)gtk_main_quit, NULL);
    g_signal_connect(G_OBJECT("measure"), "clicked", (GCallback)ofruta, spinners);

    canvas = goo_canvas_new ();

    gtk_widget_set_size_request (canvas, 600, 465);
    goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 1000);
    gtk_widget_show (canvas);

    gtk_container_add (GTK_CONTAINER (gtk_builder_get_object( builder, "draw_area" )), canvas);

    root = goo_canvas_get_root_item (GOO_CANVAS (canvas));

    /* Destroy builder, since we don't need it anymore */
    g_object_unref( G_OBJECT( builder ) );

    /* Show window. All other widgets are automatically shown by GtkBuilder */
    gtk_widget_show( window );

    /* Start main loop */
    gtk_main();

    return( 0 );
}

当单击名为 "measure" 的按钮时,它的处理程序调用了 "ofruta" 在 "ofruta" 中调用绘图函数。

这是正确的方法吗?

这是一个基于 https://developer.gnome.org/goocanvas/unstable/goocanvas-model-view-canvas.html 的例子:

#include <stdlib.h>
#include <goocanvas.h>

static gboolean on_rect_button_press (GooCanvasItem  *view,
        GooCanvasItem  *target,
        GdkEventButton *event,
        gpointer        data);

static gboolean on_delete_event      (GtkWidget      *window,
        GdkEvent       *event,
        gpointer        unused_data);


GooCanvasItemModel *root, *rect_model, *text_model, *path;

int main (int argc, char *argv[]) {
    GtkWidget *window, *scrolled_win, *canvas;
    GooCanvasItem *rect_item;

    gtk_set_locale ();
    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
    gtk_widget_show (window);
    g_signal_connect (window, "delete_event", (GtkSignalFunc) on_delete_event,
            NULL);

    scrolled_win = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
            GTK_SHADOW_IN);
    gtk_widget_show (scrolled_win);
    gtk_container_add (GTK_CONTAINER (window), scrolled_win);

    canvas = goo_canvas_new ();
    gtk_widget_set_size_request (canvas, 600, 450);
    goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 1000);
    gtk_widget_show (canvas);
    gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);

    root = goo_canvas_group_model_new (NULL, NULL);

    rect_model = goo_canvas_rect_model_new (root, 100, 100, 400, 400,
            "line-width", 10.0,
            "radius-x", 20.0,
            "radius-y", 10.0,
            "stroke-color", "yellow",
            "fill-color", "red",
            NULL);

    text_model = goo_canvas_text_model_new (root, "Hello World", 300, 300, -1,
            GTK_ANCHOR_CENTER,
            "font", "Sans 24",
            NULL);
    goo_canvas_item_model_rotate (text_model, 45, 300, 300);

    goo_canvas_set_root_item_model (GOO_CANVAS (canvas), root);

    GooCanvasLineDash *dash = goo_canvas_line_dash_new (2, 5.0, 5.0);
    const char *buf = "M 0 128 L 1000 256";
    path = goo_canvas_path_model_new (root, buf,
            "stroke-color", "red",
            "line-dash", dash,
            NULL);

    rect_item = goo_canvas_get_item (GOO_CANVAS (canvas), rect_model);
    g_signal_connect (rect_item, "button_press_event",
            (GtkSignalFunc) on_rect_button_press, NULL);

    goo_canvas_line_dash_unref(dash);

    gtk_main ();

    return 0;
}


static gboolean on_rect_button_press (GooCanvasItem  *item,
        GooCanvasItem  *target,
        GdkEventButton *event,
        gpointer        data) {
    g_print ("rect item received button press event\n");

    static float a = 128, b = 256;
    a += 16, b += 16;

    char buf[64];
    snprintf(buf, sizeof(buf), "M 0 %f L 1000 %f", a, b);
    g_object_set(G_OBJECT(path), "data", buf, NULL);

    return TRUE;
}


static gboolean on_delete_event (GtkWidget *window,
        GdkEvent  *event,
        gpointer   unused_data) {
    exit (0);
}

通过将路径的 data 属性 修改为 g_object_set 它会在单击矩形时移动。属性名称应取自文档,例如https://developer.gnome.org/goocanvas/unstable/GooCanvasPathModel.html