[gelöst][gtk][css] genereller und individueller Widget Style mit css



  • Hallo c-community,

    ich habe ein kleines Testprogramm geschrieben, um css-Styles in gtk einzubinden:
    gtkTest.h

    #ifndef     GtkTestHeader
    #define     GtkTestHeader
    
    #define     _BSD_SOURCE
    
    #include    <stdio.h>   //  for printf
    //#include    <stdlib.h>
    #include    <string.h>  //  for css
    #include    <gtk/gtk.h> //  for gtk
    
    #endif
    

    gtkTest.c

    #include    "gtkTest.h"
    
    int main(int argc, char **argv){
    
        gtk_init(&argc, &argv);
    
        GtkBuilder *_builder            =   gtk_builder_new();
        gtk_builder_add_from_file(_builder, "sources/window.glade", NULL);
        gtk_builder_connect_signals(_builder, NULL);
    
        GtkWidget   *_windowTest        =   GTK_WIDGET(gtk_builder_get_object(_builder, "WindowTest"));
        g_signal_connect(GTK_WINDOW(_windowTest), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    
        /*CSS**********************************************************************/
    
        GdkDisplay      *_windowDisplay =   gdk_display_get_default();
        GdkScreen       *_windowScreen  =   gdk_display_get_default_screen(_windowDisplay);
        GError          *_error         =   NULL;
        GtkCssProvider  *_cssProvider   =   gtk_css_provider_new();
    
        gtk_style_context_add_provider_for_screen(_windowScreen, GTK_STYLE_PROVIDER (_cssProvider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    
    /*    gsize            _bytesWritten, _bytesRead;*/
    /*    const gchar     *_cssFile       =   "sources/window.css";*/
    
        gtk_css_provider_load_from_data(_cssProvider,
                                        "GtkWindow{\n"
                                        "   background-image: -gtk-gradient(linear, left top, right top, from(rgb(0,0,70)), to(rgb(255,255,255)));\n"
                                        "}\n"
                                        "GtkLabel{\n"
                                        "   color: red;\n"
                                        "}\n",
                                        -1,
                                        &_error);
    
    /*    gtk_css_provider_load_from_path(_cssProvider,*/
    /*                                    g_filename_to_utf8(_cssFile, (gssize)strlen(_cssFile), &_bytesRead, &_bytesWritten, &_error),*/
    /*                                    NULL);*/
    
        g_object_unref(_cssProvider);
    
        /*CSS*END******************************************************************/
    
        gtk_widget_show_all(_windowTest);
        g_object_unref(G_OBJECT(_builder));
    
        gtk_main();
    
        return 1;
    }
    

    Das fertige Fenster hat einfach ein Window mit Label, welche über die css-Daten formatiert werden. Es funktioniert auch!!

    Meine Frage: Wenn ich auf einem Fenster mehrere gleiche Elemente (z.B. Labels) habe kann ich diese über den Teil:

    "GtkLabel{\n"
    "   color: red;\n"
    "}\n"
    

    Gleichmäßig formatieren. Wenn ich aber nicht alle Elemente gleich haben will, sonder 2 Gruppen (5 Labels haben grüne Farbe und 6 haben gelbe Farbe), wie kann ich das entsprechend über css mitteilen? Wie spreche ich unterschiedliche Gruppen gleichen Types an? Wie spreche ich einzelne Elemente an?

    Ich habe folgendes versucht:

    "#LabelTest{\n"
    "   color: blue;\n"
    "}\n"
    

    Damit wollte ich das GtkLabel LabelTest anders färben, aber leider hat dies nicht funktioniert!

    Hoffe jemand kann mir hier helfen

    mirrowwinger



  • Ich habe mit gtk_css_provider bisher keine Erfahrung - bin aber nach kurzer Suche auf die Dokumentation gestossen:

    https://developer.gnome.org/gtk3/stable/GtkCssProvider.html

    Wer schon CSS und HTML in die Tastatur geklopft hat (wie ich), sieht recht schnell, wie es heissen könnte - ich betone könnte:

    GtkLabel#LabelTest{
       color: blue
    }
    

    Vielleicht hilft Dir der Tipp ja...

    PS: Ich habe mir das Ganze etwas näher angeschaut - Mit dieser Technik tun sich ja geniale "Designwelten" auf... wow



  • @abcdefg danke für deine Mühen. Ich habe die Dokumentation auch gefunden. Fast alle der Möglichkeiten habe ich getestet! Lustig ist, die einzige die nicht funtionieren (sind die ich bräuchte):

    GtkLabel#LabelTest{
    ...
    }
    

    sowie:

    #LabelTest{
    ...
    }
    

    Was zu funktionieren scheint:

    GtkNotebook > GtkEntry{
    ...
    }
    

    Werde ich mal schauen, ob ich damit auskomme.

    MfG

    mirrowwinger



  • Zeigst Du mal das Glade-File - dann würde ich schon aus Interesse mal ein wenig rumtesten....



  • <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <!-- interface-requires gtk+ 3.0 -->
      <object class="GtkWindow" id="WindowTest">
        <property name="can_focus">False</property>
        <property name="window_position">center-on-parent</property>
        <property name="default_width">200</property>
        <property name="default_height">200</property>
        <child>
          <object class="GtkLabel" id="LabelTest">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">labelTest</property>
          </object>
        </child>
      </object>
    </interface>
    

    Kann es daran liegen, dass die id="LabelTest" ist? In Glade steht da immer Name oder ist das egal?

    [Edit1] Genau das ist das Problem, die id aus der Glade scheint nicht der Name zu sein!!!! Wenn ich also mein Laden des GtkWidgets wie folgt ändere:

    GtkWidget   *_labelTest        =   GTK_WIDGET(gtk_builder_get_object(_builder, "LabelTest"));
    gtk_widget_set_name(_labelTest, "LabelTest");
    

    Dann scheint es zu gehen.[/Edit1]



  • Danke - ich schaus mir mal an....



  • Ok das ist der Trick: Folgende Änderung MUSS im glade (xml) File hinzugefügt werden:

    <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <!-- interface-requires gtk+ 3.0 -->
      <object class="GtkWindow" id="WindowTest">
       [b] <property name="name">WindowTest</property>[/b]
        <property name="can_focus">False</property>
        <property name="window_position">center-on-parent</property>
        <property name="default_width">200</property>
        <property name="default_height">200</property>
        <child>
          <object class="GtkLabel" id="LabelTest">
            [b]<property name="name">LabelTest</property>[/b]
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">labelTest</property>
          </object>
        </child>
      </object>
    </interface>
    

    Jetzt kann ich die GtkWidgets in der css File mit ihren Namen ansprechen:

    #WindowTest{
    ...
    }
    
    #LabelTest{
    ...
    }
    

    Problem gelöst.



  • Gut - dann ist ja alles klar... 👍 🙂



  • @abcdefg: Trotzdem Danke ohne deinen Hinweis nochmal auf den glade-code anzuschauen, wäre mir das wohl nicht aufgefallen!


Log in to reply