Anfängerproblem! GTK DrawingArea



  • Hi,
    ich bin gerade dabei mir C beizubringen und bräuchte mal ne kleine Hilfe weil ich mit den ganzen Tutorials im Netz nicht klarkomme. Ich versuche gerade meine Python Programme in C zu übersetzen und hab grad echt keine Ahnung wie ich das mit der GTK DrawingArea hinbekomme.
    Ich hab mit glade ein fenster mit 3 Drawingareas erstellt, aber wie zeichne ich da jetzt rein? Es muß doch genauso wie in Python mit einer colormap, einem graphic context usw. gehen. Nur wie? Könnt ihr bitte meine 'Versuch' irgendwas zu zeichnen vervollständigen so das ichs wieder verstehe?

    #include <gtk/gtk.h>
    
    int main (int argc, char *argv[])
    {
    	GtkBuilder *builder;
    	GError *error = NULL;
    	GtkWidget *window, *darea1, *darea2, *darea3;
    
    	gtk_init (&argc, &argv);
    	builder = gtk_builder_new ();
    	gtk_builder_add_from_file (builder, "kolli.ui", &error);
    	window = GTK_WIDGET(gtk_builder_get_object (builder, "window"));
    	g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    	darea1 = GTK_WIDGET(gtk_builder_get_object (builder, "darea1"));
    	darea2 = GTK_WIDGET(gtk_builder_get_object (builder, "darea2"));
    	darea3 = GTK_WIDGET(gtk_builder_get_object (builder, "darea3"));
    
    	gtk_widget_show_all (window);
    	gtk_main ();
    	return 0;
    }
    

    Gruß Tom



  • Hallo,

    Zunächst solltest Du natürlich Dein Glade File zeigen und Deinen restlichen Code. Ich habe mit einfachem Googeln eine Seite mit Code gefunden, der sich compilieren lässt:

    http://www.jroller.com/RickHigh/entry/gtk_drawing_example_done_in

    Das Progamm lässt sich nach #include der Standardlibraries in einem GTK+ Environment umwandeln (es gibt zwei Warnings) und scheint zu funktionieren. Man sieht schön, wie das mit den Signalen zusammenspielt....

    Vielleicht hilfts 😉



  • Wie gesagt, bin noch am Anfang und das ist bis jetzt schon mal der ganze Code.
    Das ist die glade Datei:

    <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <!-- interface-requires gtk+ 2.0 -->
      <object class="GtkWindow" id="window">
        <property name="app_paintable">True</property>
        <property name="can_focus">False</property>
        <property name="title" translatable="yes">Kollisionsüberwachung</property>
        <child>
          <object class="GtkVBox" id="box2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">Kollisionsüberwachung</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkDrawingArea" id="darea1">
                <property name="width_request">640</property>
                <property name="height_request">100</property>
                <property name="visible">True</property>
                <property name="app_paintable">True</property>
                <property name="can_focus">False</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkDrawingArea" id="darea2">
                <property name="width_request">640</property>
                <property name="height_request">100</property>
                <property name="visible">True</property>
                <property name="app_paintable">True</property>
                <property name="can_focus">False</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <object class="GtkDrawingArea" id="darea3">
                <property name="width_request">640</property>
                <property name="height_request">100</property>
                <property name="visible">True</property>
                <property name="app_paintable">True</property>
                <property name="can_focus">False</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">3</property>
              </packing>
            </child>
          </object>
        </child>
      </object>
    </interface>
    

    Einfach einen roten Strich in einer der DrawingAreas zeichnen damit ich die Syntax verstehe. In Python wäre das so:

    colormap = darea.get_colormap()
    gcroh = darea.window.new_gc()
    red=colormap.alloc_color(65535,0,0)
    gcroh.foreground=red
    gcroh.line_width = 2
    darea.window.draw_line(gcroh,10,10,90,70)
    

    Gruß Tom



  • Ich kenne Python zu wenig - aber es scheint mir, dass diese Sprache im zusammenhang mit GTK+ extrem "abstrakt" ist. Das ist mit C und GTK+ nicht so. Wenn Du mit C und GTK+ programmieren möchtest, gehst Du an den Kern der Sache und hast nicht ein paar Layer, die alles mögliche implizieren oder nicht. Abe das ist ja geade das schöne daran.

    Wenn ich Deinen Code in Deinem 1. Post anschaue, scheint es, dass Du noch ganz am Anfang dieses Abenteuers bist. Und ja - lege Dir die neuste Vesion von Glade zu (GTK+ 2.0 ist schon recht alt). Wenn Du wirklich in diese Welt einsteigen willst, beschäftige Dich mit Cairo (gerade im Zusammenhang mit Grafiken), GLib (viele tolle Funktionen) - es gibt noch weitere Dinge - aber das findest Du dann schon raus.
    Hier habe ich einen Code (ohne Glade), der drei Rechtecke in roter Farbe zeichnet (übernommen von http://zetcode.com/tutorials/cairographicstutorial/basicdrawing/ ):

    #include <cairo.h>
    #include <gtk/gtk.h>
    
    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {
      cairo_t *cr;
    
      cr = gdk_cairo_create (widget->window);
    
      cairo_set_source_rgb(cr, 255, 0, 0);
    
      cairo_rectangle(cr, 30, 30, 100, 100);
      cairo_set_line_width(cr, 14);
      cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); 
      cairo_stroke(cr);
    
      cairo_rectangle(cr, 160, 30, 100, 100);
      cairo_set_line_width(cr, 14);
      cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL); 
      cairo_stroke(cr);
    
      cairo_rectangle(cr, 100, 160, 100, 100);
      cairo_set_line_width(cr, 14);
      cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); 
      cairo_stroke(cr);
    
      cairo_destroy(cr);
    
      return FALSE;
    }
    
    int main (int argc, char *argv[])
    {
      GtkWidget *window;
      GtkWidget *darea;  
    
      gtk_init(&argc, &argv);
    
      window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
      darea = gtk_drawing_area_new();
      gtk_container_add(GTK_CONTAINER(window), darea);
    
      g_signal_connect(darea, "expose-event",
          G_CALLBACK(on_expose_event), NULL);
      g_signal_connect(window, "destroy",
          G_CALLBACK(gtk_main_quit), NULL);
    
      gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
      gtk_window_set_default_size(GTK_WINDOW(window), 300, 280); 
    
      gtk_widget_show_all(window);
    
      gtk_main();
    
      return 0;
    
    }
    

    Das kannst Du so compilieren, wie er dasteht.

    Vielleicht noch ein Wort zu Glade:
    Glade bietet viele nützliche Funktionen, die das Leben manchmal einfacher machen können. Ich benutze Glade hauptsächlich, wenn ich Labels, Eingabefelder, Buttons und ähnliches benötige - alles andere ist in der Regel schneller programmiert.
    Vielmehr kann ich Dir nicht empfehlen und wünsche Dir viel Erfolg mit GTK+ und C!



  • Danke für die Antwort. Hat mir echt geholfen!
    Jetzt hab ich nur noch ein Problem: Wie kann ich aus einer anderen Funktion das expose-event auslösen?
    Hier mal ein kleiner Ausschnitt meines Codes (Der komplette ist schon einige hundert Zeilen lang):

    .....................
    void berechnung() {
    	while (1) {
    		..........
    
    	}
    	return;
    }
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
    
    	cairo_t *cr;
    
    	cr = gdk_cairo_create (widget->window);
    
    	cairo_set_source_rgb(cr, 0, 0, 0);
    
    	cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    	cairo_set_font_size(cr, 23.0);
    	cairo_move_to(cr, 150.0, 35.0);
    	cairo_show_text(cr, "Test");
    
            ................................
    
    	cairo_destroy(cr);
    
    }
    
    int kontrollfenster(int argc, char *argv[]) {
    	GtkWidget *window;
    	GtkWidget *darea;
    	gtk_init(&argc, &argv);
    
    	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_title(GTK_WINDOW(window), "Fenster");
    
    	darea = gtk_drawing_area_new();
    	gtk_container_add(GTK_CONTAINER(window), darea);
    
    	g_signal_connect(darea, "expose-event", G_CALLBACK(on_expose_event), NULL);
    	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    
    	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    	gtk_window_set_default_size(GTK_WINDOW(window), 640, 450);
    
    	gtk_widget_show_all(window);
    
    	g_idle_add ((GSourceFunc) berechnung, NULL);
    	gtk_main();
    
    }
    ....................
    

    Da wo die Punkte sind steht viel Code den ich euch mal ersparen möchte 😃
    Ich müsste in der Funktion berechnung irgendwie das expose-event auslösen. Nur wie? Von selbst macht er das nicht. Einmal das Fenster minimiert, bleibt es leer. Und ich möchte ja auch das es nach der Berechnung mit den neuen Werten neu gezeichnet wird.

    Gruß Tom



  • Hab das Problem schon erkannt. Eine Endlosschleife wo keine sein soll.....

    Danke trotzdem an alle!


Anmelden zum Antworten