Gtk+ bzw C Frage



  • Das in Gtk+ enthaltene GdkColor ist wie folgt definiert:

    typedef struct {
      guint32 pixel;
      guint16 red;
      guint16 green;
      guint16 blue;
    } GdkColor;
    

    Nun habe ich kleine Miniprogrämmchen umgeschrieben, die Linien und Kreise und so in verschiedenen Farben in Gtk+ zeichnen sollen und auch alle ganz gut funktionieren.

    Folgender Programmausschnitt läuft perfekt:

    static GdkPixmap *pixmap = NULL;
    GdkGC *mygc;
    mygc = gdk_gc_new (pixmap);
    
    const GdkColor blau = { 0, 0, 0, 0xffff };
    gdk_gc_set_rgb_fg_color (mygc, &blau);
    gdk_draw_line (pixmap, mygc, 200, 50, 50, 250);
    

    Das zeichnet nun eine blaube Linie in das Fenster.

    Auch ein nachträgliches ändern der Farbwerte ist möglich:

    GdkColor lila = { 0, 0, 0, 0};
    lila.blue = 65535;
    lila.red = 65535;
    gdk_gc_set_rgb_fg_color (mygc, &lila);
    gdk_draw_line (pixmap, mygc, 100, 10, 200, 120);
    

    Auch folgendes ist möglich:

    GdkColor *rot;
    GdkColor rot2;
    //rot2.pixel = 100;
    rot2.red = 65535;
    rot2.green = 0;
    rot2.blue = 0;
    rot=&rot2;
    
    gdk_gc_set_rgb_fg_color (mygc, rot);
    gdk_draw_line (pixmap, mygc, 150, 50, 250, 250);
    

    Und wenn ich nachträglich die Werte in rot zu einem Grün andern möchte so geht es über

    rot->green = 65535;
    rot->red = 0;
    gdk_gc_set_rgb_fg_color (mygc, rot);
    gdk_draw_line (pixmap, mygc, 0, 50, 200, 150);
    

    Bloß - und jetzt kommt meine Frage - schon allein die eingabe von folgendem führt zu einem Speicherzugriffsfehler:

    GdkColor *gruen;
    gruen->green = 65535;  /* Speicherzugriffsfehler (Segmentation fault) */
    

    Wie kommt das??

    Desweiteren hätte ich noch eine weitere Frage, die jedoch nur Gtk+ Entwickler beantworten können.

    Gibt es eine Möglichkeit eine Linie in ein Fenster zu zeihnen, ohne externe Funktionen zu schreiben? Also alles in main().

    Gewöhnlich steht in einem Gtk+ Programm folgendes:

    g_signal_connect (G_OBJECT (drawing_area), "expose_event",
    		    G_CALLBACK (expose_event), NULL);
    
      g_signal_connect (G_OBJECT (drawing_area),"configure_event",
    		    G_CALLBACK (configure_event), NULL);
    

    Diese beiden Zeilen erstellen irgendwie Zugriffe auf Funktionen (die man noch selber hinzufügen muß) die
    static gboolean configure_event( GtkWidget *widget, GdkEventConfigure *event ){}
    und
    static gboolean expose_event( GtkWidget *widget, GdkEventExpose *event ){}

    heißen.

    Irgendwie passiert da jedoch so einiges was mit ANSI-C nichts mehr zu tun hat und wo ich große Verständnisprobleme mit habe.

    Vor allem werden die beiden Funktionen nach dem Aufruf des eigentlichen Programms aufgerufen. Das heißt, auch alles was unter g_signal_connect(); steht wird vor dem Programmcode abgerufen, der dann in expose_event(){} steht.

    Kann ich somit vielleicht eine Linie in ein Fenster zeichnen, ohne g_signal_connect(){} oder ähnliches (wie g_signal_connect_data(){}) zu verwenden?

    Grüße
    theuserbl



  • Was häst du von:

    GdkColor gruen;
    gruen.green = 65535;  /* kein Speicherzugriffsfehler */
    

    Zu deiner zweiten Frage:
    Es hat sehr wohl etwas mit C zu tun. Der Main Loop wartet normalerweise, bis ein vom Benutzer ausgelöstes Event auftrifft. Wenn diese Event eintritt, schaut GTK+ in einer Tabelle nach und ruft die Funktion auf, deren Pointer du vorher übergeben hast.

    Wenn du was über Funktionszeiger wissen willst, dann schau mal hier: http://www.pronix.de/pronix-747.html

    Du scheinst die Speicherverwaltung und Zeiger in C noch nicht verstanden zu haben. Du solltest dir dieses Wissen aneignen, bevor du weiter mit GTK+ programmierst.



  • Danke für die schnelle Antwort.

    ProgChild schrieb:

    Was häst du von:

    GdkColor gruen;
    gruen.green = 65535;  /* kein Speicherzugriffsfehler */
    

    Ja, ich weiß das das geht. Ich meine es auch schon mal ausprobiert zu haben.

    Aber es wundert mich schon etwas, daß das was ich schrieb bei rot* über den Umweg rot funktioniert, aber bei gruen* es ohne diesen Umweg nicht geht.

    Zu deiner zweiten Frage:
    Es hat sehr wohl etwas mit C zu tun. Der Main Loop wartet normalerweise, bis ein vom Benutzer ausgelöstes Event auftrifft. Wenn diese Event eintritt, schaut GTK+ in einer Tabelle nach und ruft die Funktion auf, deren Pointer du vorher übergeben hast.

    Hmm... ich glaube ich werde mich dann wohl auch erst einmal näher mit Events in C beschäftigen müssen.

    Wenn du was über Funktionszeiger wissen willst, dann schau mal hier: http://www.pronix.de/pronix-747.html

    Danke, werde ich mir mal angucken. Bin auch schon mal auf die Seite gestoßen. Ist das Buch von dem die Internetversion davon stammt ("C von A bis Z") gut? Das C-Buch in dem ich zu Hause immer nachschlage ist C - Programmieren von Anfang an. Wenn jedoch "C von A bis Z" zu empfehlen ist, dann werde ich es mir auch noch zulegen.

    Du scheinst die Speicherverwaltung und Zeiger in C noch nicht verstanden zu haben. Du solltest dir dieses Wissen aneignen, bevor du weiter mit GTK+ programmierst.

    Ok. Auch wenn ich bisher meinte, genug über C zu wissen, um mit GTK+ loszulegen. Und das was ich nicht weiß, nebenher verstehen zu können.

    Grüße
    theuserbl



  • Die Definition "GdkColor* green;" erzeugt dir nur einen Zeiger, der irgendwo ins Nirvana zeigt - um damit arbeiten zu können, mußt du ihn auf ein gültiges GdkColor-Objekt umbiegen (das kann ein lokales Objekt wie bei deinem "rot=&rot2;"-Beispiel sein ober auch ein Heap-Objekt):

    GdkColor* gruen = new GdkColor;
    gruen->green=0xFFFF;
    ...
    delete gruen;
    

Anmelden zum Antworten