Zeichnen mit GTK+ und C (gelöst!)



  • Hallo,

    ich möchte unter C und GTK+ zeichnen können. Mein Problem ist, das ich zeichnen kann, aber diese Zeichnung nicht fixieren kann. Also sobald die Fenstergröße verändert oder was drüber gelegt wird, wird der Inhalt gelöscht. Wie kann ich dieses Problem lösen? Meine Vermutung ist, das ich einfach das Bild in den Speicher lege und bei einem Expose diese wieder auf das Fenster plotte. Gibt es dazu Lösungen im Internet?

    Gruß HansimGlück



  • Du musst das Widget jedes mal neu zeichnen, wenn das Signal "expose-event" ausgelöst wurde (passiert beim ersten Anzeigen und wenn du halt ein anderes Fenster darüber schiebst).



  • Danke für Deine Antwort,

    ja, das weis ich. Aber: Woher bekomme ich die Daten, in dem Beschrieben ist, wie es zuvor aussah. Wenn ich es mache, wird ein leeres Fenster erzeugt. Hm?

    Gruß, HansimGlück



  • Schreib's in ein GdkPixmap weg. Das ist ein "offscreen drawable". Den Inhalt des GdkPixmaps solltest du dannn wieder auf dein Fenster zeichnen können.



  • Kann ich direkt in die GdkPixmap schreiben?

    Bisher hab ich das so gemacht:

    gdk_draw_line (area->window, area->style->fg_gc[GTK_WIDGET_STATE (area)], posx1,posy1,posx2,posy2);
    

    wobei das "area" mein widget (drawingarea) ist.

    etwa so?

    gdk_draw_line(pixmap,area->style->fg_gc[GTK_WIDGET_STATE (area)], posx1,posy1,posx2,posy2);
    

    und wie kopiere ich es dann in mein Widget?

    Gruß, HansimGlück



  • Hallo,

    ich hab da mal was probiert:

    #include <glade/glade.h>
    #include <gtk/gtk.h>
    
    int win_x=800;
    int win_y=600;
    GdkPixmap *pixmap=NULL;
    GdkGC *MeinGC;
    
    static gboolean button_pressed (GtkWidget *area, GdkEventButton *event, gpointer data)
    {
      GdkRectangle update_rect;
    
      update_rect.x = event->x;
      update_rect.y = event->y;
      update_rect.width = 1;
      update_rect.height = 1;
    
      gdk_draw_point(pixmap,MeinGC,event->x,event->y);
    
      gdk_window_invalidate_rect (area->window,&update_rect,FALSE);
    
      return TRUE;
    }
    
    static gboolean expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
      gdk_draw_drawable (widget->window, MeinGC, pixmap, event->area.x, event->area.y, event->area.x, event->area.y, win_x, win_y);
      return FALSE;
    }
    
    gboolean configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data)
    {
      pixmap = gdk_pixmap_new (widget->window, win_x, win_y, -1);
      gdk_draw_rectangle (pixmap, widget->style->white_gc, TRUE, 0, 0, win_x, win_y);
      MeinGC = gdk_gc_new (widget->window);
      return TRUE;
    }
    
    int main (int argc, char *argv[])
    {
      GladeXML *xml;
      GtkWidget *win,*draw;
    
      gtk_init (&argc, &argv);
    
      xml = glade_xml_new ("paint1.glade",NULL,NULL);
      win = glade_xml_get_widget (xml, "window");
      draw = glade_xml_get_widget (xml, "draw");
    
    // Events:
    
      gtk_widget_add_events (draw, GDK_BUTTON_PRESS_MASK);
    
      g_signal_connect (G_OBJECT (draw), "configure_event", G_CALLBACK (configure_event), NULL);
      g_signal_connect (G_OBJECT (draw), "expose_event", G_CALLBACK (expose_event), NULL);
    
      g_signal_connect (G_OBJECT (draw), "button_press_event", G_CALLBACK (button_pressed), NULL);
    
      glade_xml_signal_autoconnect (xml);
      gtk_widget_show_all (win);
      gtk_main ();
    
      return 0;
    }
    

    Die Glade-Datei:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
    <!--Generated with glade3 3.4.3 on Tue Jul 22 12:58:15 2008 -->
    <glade-interface>
      <widget class="GtkWindow" id="window">
        <property name="title" translatable="yes">Ein Malprogramm</property>
        <property name="icon">einhorn.jpg</property>
        <signal name="delete_event" handler="gtk_main_quit"/>
        <signal name="destroy_event" handler="gtk_main_quit"/>
        <child>
          <widget class="GtkDrawingArea" id="draw">
            <property name="visible">True</property>
          </widget>
        </child>
      </widget>
    </glade-interface>
    

    Dieses Programm funktioniert so einigermassen. Also wenn das Fenster überblendet oder Iconifiziert wird, sind meine pixel noch da! Aber sobald ich jetzt die Größe veränder ist alles weg. Warum? Wer kann mir Helfen?

    Gruß HansimGlück



  • Hallo,

    ich hab da einen kleinen Fehler drin gehabt!

    Folgendes: wird die Größe geändert, wird ein "configure_event" ausgelöst. Hier hies das, das die Pixmap wieder gelöscht wurde. Ein einfaches "if" hat diesen Fehler beseitigt.

    Danke nochmal, gruß HansimGlück


Anmelden zum Antworten