Funktionsaufruf in ereignisgesteuerter Umgebung

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
jolico
Beiträge: 4
Registriert: Do Mär 31, 2016 9:40 pm

Funktionsaufruf in ereignisgesteuerter Umgebung

Beitrag von jolico » So Apr 17, 2016 11:38 am

Hallo,

versuche in die Geheimnisse der event gesteuerten Programmierung mit Gtk+ und cairo vorzudringen, aber an folgendem Problem komme ich nicht so recht weiter :

Gegeben sei die Programmsituation :

Code: Alles auswählen

void verarbeite_daten(GtkButton *trigger, gpointer entry)
{
  /* die hier verarbeiteten Daten sind anschließend automatisch in
     die drawing area 'darea' auszugeben                            

     dazu soll hier vom Programm on_draw_event() aufgerufen werden. */
}

static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
   zeichne_was(cr);
   schreibe_was(cr);
   return FALSE;
}

int main(int argc, char** argv)
{
   /* der übliche Programm-Aufbau */

   /* in diese drawing area sollen die Ausgaben erfolgen */
   darea = gtk_drawing_area_new();

   /* hier wird die Verarbeitung der Daten angestoßen */
   g_signal_connect(button, "clicked", G_CALLBACK(verarbeite_daten), entry);
	
   /* erstmalige Daten-Ausgabe bei Programmstart, (Basis-Information) */
   g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL);

   /* weiterer Programmcode */
}

Frage : Wie kann ich aus der Funktion 'verarbeite_daten()' die Funktion 'on_draw_event()' aufrufen ?

Da es an dieser Stelle keinen Button, Mausklick o.ä. gibt, muss das Signal vom Programm selbst erzeugt werden.

In https://developer.gnome.org/gobject/uns ... gnals.html habe ich mit g_signal_new() und g_signal_emit()
zwar zwei mögliche Kandidaten dafür gefunden, aber mangels Vorwissen sind die dort gegebenen Hinweise für mich noch wenig verständlich. Ich bräuchte das etwas mehr für Einsteiger-Niveau aufbereitet. Vielleicht gibt es ja auch noch andere Lösungsansätze.

Ich hoffe, Ihr könnt mir da weiterhelfen.

Danke
jolico

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Funktionsaufruf in ereignisgesteuerter Umgebung

Beitrag von Xin » So Apr 17, 2016 12:24 pm

Nehmen wir es zunächst etwas Insiderwissen: für die Funktion brauchst Du nur cr, also kannst Du den Rest auch einfach weglassen:

Code: Alles auswählen

  void verarbeite_daten(GtkButton *trigger, gpointer entry)
{
  cairo_t *cr = do_some_magic();
  on_draw_event( NULL, cr, NULL );
}
Da die on_draw_event( ... ) aber irgendwann vielleicht das Widget oder Userdata wirklich braucht, wäre es wohl sinnvoller, die Geschichte so auszulagern, dass Du eine Funktion updata_cairo( cairo_t * cr ) hast, die Du von verarbeite_daten() und on_draw_event() aufrufst, die eben kein Widget oder Userdata braucht.

on_irgendwas() Funktionen sind für die GUI gedacht. Die aufzurufen solltest Du wirklich nur aus einem GUI-Context heraus machen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

jolico
Beiträge: 4
Registriert: Do Mär 31, 2016 9:40 pm

Re: Funktionsaufruf in ereignisgesteuerter Umgebung

Beitrag von jolico » Do Apr 21, 2016 11:12 pm

Vielen Dank für Deine schnelle Antwort.

Die Bezeichnungen habe ich aus Beispielen verschiedener Tutorials übernommen, die ich derzeit kombiniere, um mich voranzutasten. Programmierkonventionen sind mir da noch nicht geläufig.

Daß es besser ist, die Ausgabefunktion auszulagern, habe ich verstanden, kann das aber noch nicht umsetzen. Bei '_some_magic' habe ich eine größere Wissenslücke.

In meinem Programmfragment wird zur erstmaligen Daten-Ausgabe mit g_signal_connect … die Callback-Funktion on_draw_event aufgerufen. Diese enthält bereits den Cairo-context cairo_t *cr. Mir ist nicht klar, wie, wo und mit welchen Parametern dieser erzeugt wird.

Entsprechend müsste ich in der Funktion verarbeite_daten() ein cairo_t *cr für die Ausgabe an das Widget darea erzeugen. (Evtl. mit cairo_create ?) darea ist in verarbeite_daten() local nicht bekannt.

Könntest Du mir bitte die Zusammenhänge etwas detaillierter erläutern ?
Gibt es vielleicht ein Buch, in dem solche Zusammenhänge ausführlicher dargestellt werden ?

Danke
jolico

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Funktionsaufruf in ereignisgesteuerter Umgebung

Beitrag von Xin » Fr Apr 22, 2016 8:59 am

jolico hat geschrieben:Bei '_some_magic' habe ich eine größere Wissenslücke.

In meinem Programmfragment wird zur erstmaligen Daten-Ausgabe mit g_signal_connect … die Callback-Funktion on_draw_event aufgerufen. Diese enthält bereits den Cairo-context cairo_t *cr. Mir ist nicht klar, wie, wo und mit welchen Parametern dieser erzeugt wird.

Entsprechend müsste ich in der Funktion verarbeite_daten() ein cairo_t *cr für die Ausgabe an das Widget darea erzeugen. (Evtl. mit cairo_create ?) darea ist in verarbeite_daten() local nicht bekannt.

Könntest Du mir bitte die Zusammenhänge etwas detaillierter erläutern ?
Gibt es vielleicht ein Buch, in dem solche Zusammenhänge ausführlicher dargestellt werden ?
Wenn ich das richtig verstehe, ist cairo_t das Ziel auf dem Du zeichnen willst. do_some_magic() sagt genau das, was Du fragst: Ich habe keine Ahnung, wo Du zeichnen willst, also musst Du in Deiner Funktion verarbeite_daten() irgendwo auch irgendwo herausfinden, wo Du eigentlich zeichnen willst, damit Du es an on_draw_event übergeben kannst. Genauso musst Du es in meiner Lösung an updata_cairo() übergeben.

Wenn Du dein Programm startest wirst Du ja vermutlich einen Cairo Render-Kontext erstelllen? Und den musst Du Dir irgendwo merken. do_some_magic() muss sich den Kontext dann holen.

Erzeugst Du einen neuen Cairo-Kontext, zeichnest Du auch woanders hin.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten