[Gtk] Schachbrett ähnliches Bedienungsfeld



  • Hallo ich versuche gerade meinem Programm eine Benutzeroberfläche mit Gtk zu verpassen,
    ich fange deshalb gerade erst mit Gtk an.

    Nur brauch ich nun eine Art Schachbrett, also es ist ein sehr großes (ca. 50x50),
    es sollten wie bei einem Schachbrett auch Quadrate sein mit, 1px Trennlinie dazwischen,
    die Quadrate selbst sind nur 10px groß.
    Ihre farbe sollte auch veränderbar sein, und sie sollten anklickbar sein.

    Ich hatte mir überlegt das mit Buttons zu lösen, auf die ich ein Image packe,
    nur sind das ein bisschen viele Button bei der Größe
    und es wäre auch schwer zu händeln alle nacheinander abzufragen, welchen Zustand sie denn gerade haben.

    Vielleicht kennt ja jemand ein Widget mit dem das einfach realisierbar wäre.



  • Ich weiss ja nicht genau, was Du realisieren möchtest... aber um so ein Schachbrett-ähnliches Gitter in einem Fenster zu arrangieren würde ich GtkTable mit den entsprechenden Werten in ein Fenster packen. Ich gehe mal davon aus, dass Du noch 2.x verwendest - hier die Doku:
    http://developer.gnome.org/gtk/2.24/GtkTable.html



  • ich verwende eigentlich version 3 unter Linux mit C und das ich das Layout/Muster mit einem Table/Grid ähnlichem Widget machen müsste ist mir klar mein Problem liegt ja darin das ich keine 2500 Button selber schreiben und abfragen will.
    Das wird dann ja nur unübersichtlich und viel zu groß



  • JulianS schrieb:

    ich verwende eigentlich version 3 unter Linux mit C und das ich das Layout/Muster mit einem Table/Grid ähnlichem Widget machen müsste ist mir klar mein Problem liegt ja darin das ich keine 2500 Button selber schreiben und abfragen will.
    Das wird dann ja nur unübersichtlich und viel zu groß

    Naja, wenn Du 50 x 50 = 2500 Felder/Widgets oder was auch immer seperat ansprechen willst, musst Du wohl auch 2500 Fälle vorsehen. Jetzt bleibt die Frage, was man wie vereinfachen kann:

    1.) Das Layout, also das Erstellen des Fensters
    Hier bietet sich Glade an. Du hast halt 10000+ entspricht 2500 x 4 (mindestens) Klicks um die Tabelle zu initialisieren... Natürlich - da ich Dein Vorhaben immer noch nicht kenne - man könnte das vielleicht auch mit einem intelligenten Loop bewerkstelligen o.ä. Aber 2500 sind nun mal 2500.

    2.) Die Abfrage dieser 2500 Events
    Wenn Du jeden einzelnen dieser 2500 Events seperat behandeln musst, benötigst Du wohl 2500 Callbacks, die das Ereignis behandeln...

    Ich habe ja keine Ahnung, was Du machen willst. Meine Glaskugel zeigt mir, dass Du vielleicht ne Gauss'sche Normalverteilung analysieren und graphisch darstellen möchtest, um festzustellen, welche Kugel wohin hüpft... 🤡

    Resumé: Mit Glade kannst Du die Layoutarbeit vereinfachen... in Deinem Code wirst Du viel "Copy/Paste" anwenden müssen - oder Du bist im falschen Forum.



  • Ne^^ ich möchte eigentlich nur Conway´s Game of Life darstellen und da brauch ich dann auch nur 2 Zustände.
    Und bisher wollte ich die Zustände in ein Array einlesen und auch wieder ausgeben lassen, also wie ein sehr pixeliges Display welches der User verändern kann.
    Ich hatte gedacht das es vielleicht eine möglichkeit in GTK gäbe so etwas einfach zu realisieren.
    Mit Glade habe ich mich nämlich noch nie auseinander gesetzt und wollte das auch eigentlich so lassen, da ich solche Programme ehrlich gesagt nicht mag.

    Vielleicht gibt es ja sogar irgendeine lib die soetwas vorhergesen hat oder es mir vielleicht ehrleichtert.

    Eine Idee um die Initialisierung und Verwendung einfacher zu machen, könnte man das auch mit nem Array von Pointern machen?



  • JulianS schrieb:

    Eine Idee um die Initialisierung und Verwendung einfacher zu machen, könnte man das auch mit nem Array von Pointern machen?

    Ich denke mit C und GTK wirst Du da nicht viel weiter kommen. Ich habe in einer bekannten Suchmaschine etwas gestöbert:
    http://www.pygame.org/project-Modified+Conway+Game+of+Life-2369-4026.html
    Viel mehr Tipps kann ich Dir zu dem Thema auch nicht geben - viel Erfolg!



  • Aus dem was du mir verlinkt hast wird mir jetzt nicht direkt klar warum das mit C nicht klappen wird, aber z.B. mit Python.
    Zudem bringen mir die Dateien nichts, da ich einmal Python nicht wirklich kann
    und das Programm auf meinem Pc nicht laufen will da irgendeine Datei scheinbar fehlt.



  • Ich widerspreche mir selber, natürlich geht das mit GTK+...
    Ich hatte heute etwas Zeit und habe mal ein wenig mit Cairo und timeout gespielt. Hier das Ergebnis:

    #include <cairo.h>
    #include <gtk/gtk.h>
    //
    static gboolean repeat_expose(GtkWidget *widget)
    {
      if (widget->window == NULL) return FALSE; // if window is destroyed, finish timeout
    // 
      gtk_widget_queue_draw(widget); // emmits an expose-event
    //  
      return TRUE;
    }
    //
    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {
      cairo_t *cr;
    //
      cr = gdk_cairo_create(widget->window);
    //
      gint width, height, i, j;
      static gint	flag;
      gdouble color_1, color_2;
      gtk_window_get_size(GTK_WINDOW(widget), &width, &height); //window resized??
      if (flag != 0) // switch flag from last call to get the effect
    	{
    		flag = 0;
    	}
    	else
    	{
    		flag = 1;
    	}
      for (j = 0; j < height; j+=10)
      {
    	for (i = 0; i < width; i+=10)
    		{
    		if (flag == 1)
    		{
    			flag = 0;
    			color_1 = 0;
    			color_2 = 0;
    		}
    		else
    		{
    			flag = 1;
    			color_1 = 8;
    			color_2 = 1;
    		}
    
    		cairo_set_source_rgb(cr, color_1, color_2, 0);
    		cairo_rectangle(cr, i, j, 10, 10);
    		cairo_fill(cr);
    		}
      }
    //
      cairo_destroy(cr);
    
      return FALSE;
    }
    //
    int main (int argc, char *argv[])
    {
      GtkWidget *window;
    //
      gtk_init(&argc, &argv);
    //
      window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    //
      g_signal_connect(G_OBJECT(window), "expose-event",
          G_CALLBACK(on_expose_event), NULL);
      g_signal_connect(G_OBJECT(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), 430, 580); 
      gtk_window_set_title(GTK_WINDOW(window), "Vierecke mit Cairo");
    //  sets a timer with 1000 ms (1 s) which calls "repeat_expose"
      g_timeout_add(1000, (GSourceFunc) repeat_expose, (gpointer) window);
    // emmits one (the first) expose-event
      gtk_widget_set_app_paintable(window, TRUE);
      gtk_widget_show_all(window);
    //
      gtk_main(); 
    //
      return 0;
    }
    

    Solltest Du noch mitlesen, wäre das vielleicht ein Gerüst für Dein Vorhaben. Das Programm ist allerdings nur unter GTK 2 getestet (ich habe hier nur Ubuntu 10.04). in die Routine "on_expose_event" müsstest Du eben die Logik für Dein Lebensspiel einarbeiten und die entsprechenden Vierecke (cairo_rectangle) mit den gewünschten Werten versorgen.
    Btw: Nachdem ich mich seit langem mal wieder mit der GLib und Cairo beschäftigt habe, kann ich nur sagen: "GTK+ rockt"... 🕶



  • danke ich hatte garnicht mehr erwartet das noch jemand antwortet, aber gut ich werd mir das mal angucken und ausprobieren, die logik habe ich mehr oder minder ja schon fertig, ich habe mich nur noch nicht direkt mit cairo auseinander gesetzt da ich mir seit ca. 1 monat gtk+ angucke, aber da gibt es ja genug material, danke nochmal. 😃



  • Naja, wenn Du Dein Lebensspiel realisiert hast, würden wir uns freuen, wenn Du es hier veröffentlichst.... 😉



  • OK soweit habe ich glaube ich alles verstanden muss dann halt noch son paar if´s und so reinpacken aber kann man die Felder auch anklicken, wenn ich das richtig verstanden habe werden die hier nur gemalt, so könnte der user dann die "Lebensform" sehr einfach selbst eingeben sonst würde mir jetzt im moment nur eine Eingabe in Form einer Text datei einfallen? oder habe ich was falsch verstanden?
    und ist das hier nicht falsch (benutzt du zweimal):

    widget->window
    

    müsste doch so sein:

    GTK_WINDOW(widget)
    


  • JulianS schrieb:

    OK soweit habe ich glaube ich alles verstanden muss dann halt noch son paar if´s und so reinpacken aber kann man die Felder auch anklicken, wenn ich das richtig verstanden habe werden die hier nur gemalt, so könnte der user dann die "Lebensform" sehr einfach selbst eingeben sonst würde mir jetzt im moment nur eine Eingabe in Form einer Text datei einfallen? oder habe ich was falsch verstanden?
    und ist das hier nicht falsch (benutzt du zweimal):

    widget->window
    

    müsste doch so sein:

    GTK_WINDOW(widget)
    

    Nein

    GTK_WINDOW(widget)
    

    ist nichts anderes, wie ein Cast. Wenn eine Funktion ein GtkWindow verlangt und ich habe "nur" ein Widget, kann man das mit diversen Makros casten.
    Jetzt mache ich etwas Eigenwerbung... gehe mal auf meine Homepage:
    http://www.it.mmlehmann.de
    Das was da in den Tutorials beschrieben ist, ist eigentlich recht trivial - aber... Wenn Du sie durcharbeiten möchtest, machst Du das nicht in einem oder zwei Tagen. Dort findest Du aber - entsprechend der Vorkenntnisse viele Informationen zu GTK+.
    Ach - ja... zur Steuerung Deines Lebensspiels: Baue erst mal statisch ein, welche Parameter zumindestens für einen Fall nötig sind und dann kümmere Dich um den Rolls Royce, der Parametereingabe zulässt. 😉



  • bei mir kommt aber komischer weise immer ein Fehler wenn ich widget->window benutze:

    Fehler: »GtkWidget« hat kein Element namens »window«

    und wenn ich GTK_WINDOW(widget) benutze ist es zwar nur noch eine Warnung aber eine unlogische:

    Warnung: Übergabe des Arguments 1 von »gdk_cairo_create« von inkompatiblem Zeigertyp [standardmäßig aktiviert]
    gdkcairo.h:33:12: Anmerkung: »struct GdkWindow *« erwartet, aber Argument hat Typ »struct GtkWindow *«

    das macht ja eigentlich keinen Sinn es ist doch das selbe aber er meint es wäre unterschiedlich

    irgendetwas farbliches sehe ich aber bei beiden nicht



  • Welches System benutzt Du??



  • ich benutze Ubuntu 12.04 mit GTK 3 und Anjuta steht bei mir jedenfalls so 😃



  • JulianS schrieb:

    ich benutze Ubuntu 12.04 mit GTK 3 und Anjuta steht bei mir jedenfalls so 😃

    Gut - ich habe mir das mit dem GTK3 jetzt mal angeschaut:
    Die Mädels und Buben haben da ja alles verändert...
    Work around ist eigentlich nur die GTK2 Development Files nachzuinstallieren (vergiss "libglade" nicht) und dann das obige Prog wie folgt umzuwandeln:

    gcc -Wall -g -o DeinProgname DeinProgname.c -export-dynamic `pkg-config gtk+-2.0 libglade-2.0 --cflags --libs`

    Bei mir mit GTK3 (Suse 12.1) lässt sich das Programm dann fehlerfrei compilieren und ausführen.

    Btw: So wie ich das nach einer kurzen Analyse sehe, sind mit GTK3 sämtliche alten Tutorials und Tipps und Hints quasi wertlos. Traurig. Wenn Microsoft sich das leisten würde, wären die weg vom Fenster.....

    Ach ja.. wenn Du mit GTK+ anfängst, würde ich Dir Anjuta nicht empfehelen - benutze stattdessen sowas wie Geany. Wenn Du mal eine gewisse Erfahrung hast, kannst Du Anjuta dann immernoch einsetzen.. (wobei ich denke, das willst Du dann nicht mehr 😉 )



  • ok danke ich hatte gtk3 eigentlich benutzen wollen da es neuer ist und ich nicht hinter dem standard sein wollte, aber dann wird das wohl klappen, hoffe ich mal, aber trotzdem danke.


Anmelden zum Antworten