Gtk Label - Multiline & Fill/Expand



  • Arbeite mich derzeit in das Gtk-Framework rein. Nach anfänglichen Schwierigkeiten begeistern mich die Möglichkeien eigentlich (Ok, im Vergleich zu VB ned wirklich verwunderlich, was man alles so machen kann).

    Nur für ein Problem find ich weder mit Glade, noch mit der GTK-Referenz, noch mit Google eine Lösung:

    Ich hab mehrere GtkLabels, die sich a die Fenstergröße anpassen (eigentlich is ein Teil der Labels in Checkboxen drin, weil die von Haus aus ja ned Multiline fähig sind). Ändert sich jetzt die Größe vom Fenster, wächst die Breite ned mit, bzw. wenn es mitwächst, wird der Text ned bis an den Rand gezeichnet sondern bleibt konstan an der selben Stelle (kleiner machen geht erst garned).
    Weder Fill noch Expand bringen irgendeinen Unterschied. VBox und HBox hab ich ebenfalls schon mehrmals umgestellt und alle möglichen Kombinationen versucht: Kein Erfolg.
    Mit anderen Widgetsklappts ja wunderbar (z.b. Listen).

    Gibts irgendeinen speziellen Trick, der mir helfen kann, dass der vorhandene Platz auch wirklich genutzt wird? Oder vlt. eine alternative Lösung?

    Würde mich über jede konstruktive Hilfe freuen.

    PS: Verwende C als Sprache, falls es was zur Sache tun sollte.



  • Gib's mir lieblos. Gib mir Quellcode! 😉
    Sonst kann ich nicht genau sagen, woran's liegt.



  • Die GUI ist mit Glade gebastelt, von daher bin ich mir ned sicher, welche Teile genau benötigt werden --> Füg als letzten Code-Abschnitt die create-Funktion fürs Fenster ein.

    Label-Text setzen

    void showQuestion(list<TQuestion>::iterator &q)
    {
      GtkWidget* temp;
      static char txt[4096];
    
      temp = lookup_widget(GTK_WIDGET(wndMain), "question");
      sprintf(txt, "<span size=\"x-large\" style=\"italic\">%s</span>", q->question);
      gtk_label_set_markup(GTK_LABEL(temp), txt);
    
      for(int i = 0; i<4; i++){
        sprintf(txt, "answer%dtext", i+1);
        temp = lookup_widget(GTK_WIDGET(wndMain), txt);
        gtk_label_set_label(GTK_LABEL(temp), q->answer[i]);
    
        sprintf(txt, "answer%d", i+1);
        temp = lookup_widget(GTK_WIDGET(wndMain), txt);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(temp), FALSE);
      }
    
      char *topic[2] = {0,};
      for(list<TTopic>::iterator i = topics.begin(); i != topics.end(); i++)
      {
        if(q->topic[0] == i->id)
          topic[0] = i->name;
        if(q->topic[1] == i->id)
          topic[1] = i->name;
      }
    
      temp = lookup_widget(GTK_WIDGET(wndMain), "category");
      sprintf(txt, "<span weight=\"bold\" size=\"large\">%s%s%s</span>",
              topic[0]?topic[0]:"", (topic[0]&&topic[1])?", ":"", topic[1]?topic[1]:"");
      gtk_label_set_markup(GTK_LABEL(temp), txt);
    }
    

    Fenster erzeugen

    wndMain = create_wndQuestions();
      showQuestion(currentQ);
      gtk_widget_show (wndMain);
      gtk_main ();
    

    create_wndQuestions()

    GtkWidget*
    create_wndQuestions (void)
    {
      GtkWidget *wndQuestions;
      GdkPixbuf *wndQuestions_icon_pixbuf;
      GtkWidget *vbox1;
      GtkWidget *hbox4;
      GtkWidget *scrolledwindow1;
      GtkWidget *treeview3;
      GtkWidget *vbox2;
      GtkWidget *category;
      GtkWidget *hbox4;
      GtkWidget *image3;
      GtkWidget *question;
      GtkWidget *answer1;
      GtkWidget *answer1text;
      GtkWidget *answer2;
      GtkWidget *answer2text;
      GtkWidget *answer3;
      GtkWidget *answer3text;
      GtkWidget *answer4;
      GtkWidget *answer4text;
      GtkWidget *hbuttonbox2;
      GtkWidget *btnExit;
      GtkWidget *alignment2;
      GtkWidget *hbox3;
      GtkWidget *image2;
      GtkWidget *label2;
      GtkWidget *btnBack;
      GtkWidget *alignment1;
      GtkWidget *hbox2;
      GtkWidget *image1;
      GtkWidget *label1;
      GtkWidget *btnForward;
      GtkAccelGroup *accel_group;
    
      accel_group = gtk_accel_group_new ();
    
      wndQuestions = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title (GTK_WINDOW (wndQuestions), "Rotes Kreuz");
      gtk_window_set_position (GTK_WINDOW (wndQuestions), GTK_WIN_POS_CENTER);
      gtk_window_set_default_size (GTK_WINDOW (wndQuestions), 700, 400);
      wndQuestions_icon_pixbuf = create_pixbuf ("rk-logo.png");
      if (wndQuestions_icon_pixbuf)
        {
          gtk_window_set_icon (GTK_WINDOW (wndQuestions), wndQuestions_icon_pixbuf);
          gdk_pixbuf_unref (wndQuestions_icon_pixbuf);
        }
    
      vbox1 = gtk_vbox_new (FALSE, 0);
      gtk_widget_show (vbox1);
      gtk_container_add (GTK_CONTAINER (wndQuestions), vbox1);
    
      hbox4 = gtk_hbox_new (FALSE, 0);
      gtk_widget_show (hbox4);
      gtk_box_pack_start (GTK_BOX (vbox1), hbox4, TRUE, TRUE, 0);
    
      scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
      gtk_widget_show (scrolledwindow1);
      gtk_box_pack_start (GTK_BOX (hbox4), scrolledwindow1, FALSE, FALSE, 0);
      gtk_widget_set_size_request (scrolledwindow1, 200, -1);
      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN);
    
      treeview3 = gtk_tree_view_new ();
      gtk_widget_show (treeview3);
      gtk_container_add (GTK_CONTAINER (scrolledwindow1), treeview3);
    
      vbox2 = gtk_vbox_new (FALSE, 0);
      gtk_widget_show (vbox2);
      gtk_box_pack_start (GTK_BOX (hbox4), vbox2, TRUE, TRUE, 0);
    
      category = gtk_label_new ("<span weight=\"bold\" size=\"large\">Kategorie</span>");
      gtk_widget_show (category);
      gtk_box_pack_start (GTK_BOX (vbox2), category, TRUE, TRUE, 5);
    
      hbox4 = gtk_hbox_new (FALSE, 0);
      gtk_widget_show (hbox4);
      gtk_box_pack_start (GTK_BOX (vbox2), hbox4, TRUE, TRUE, 5);
    
      image3 = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_DIALOG);
      gtk_widget_show (image3);
      gtk_box_pack_start (GTK_BOX (hbox4), image3, FALSE, TRUE, 5);
    
      question = gtk_label_new ("Frage?");
      gtk_widget_show (question);
      gtk_box_pack_start (GTK_BOX (hbox4), question, TRUE, TRUE, 0);
      gtk_label_set_line_wrap (GTK_LABEL (question), TRUE);
    
      answer1 = gtk_check_button_new ();
      gtk_widget_show (answer1);
      gtk_box_pack_start (GTK_BOX (vbox2), answer1, TRUE, TRUE, 5);
      gtk_widget_set_size_request (answer1, 500, -1);
      gtk_widget_add_accelerator (answer1, "clicked", accel_group,
                                  GDK_1, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      answer1text = gtk_label_new ("Antwort 1");
      gtk_widget_show (answer1text);
      gtk_container_add (GTK_CONTAINER (answer1), answer1text);
      gtk_label_set_line_wrap (GTK_LABEL (answer1text), TRUE);
    
      answer2 = gtk_check_button_new ();
      gtk_widget_show (answer2);
      gtk_box_pack_start (GTK_BOX (vbox2), answer2, TRUE, TRUE, 5);
      gtk_widget_add_accelerator (answer2, "clicked", accel_group,
                                  GDK_2, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      answer2text = gtk_label_new ("Antwort 2");
      gtk_widget_show (answer2text);
      gtk_container_add (GTK_CONTAINER (answer2), answer2text);
      gtk_label_set_line_wrap (GTK_LABEL (answer2text), TRUE);
    
      answer3 = gtk_check_button_new ();
      gtk_widget_show (answer3);
      gtk_box_pack_start (GTK_BOX (vbox2), answer3, TRUE, TRUE, 5);
      gtk_widget_add_accelerator (answer3, "clicked", accel_group,
                                  GDK_3, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      answer3text = gtk_label_new ("Antwort 3");
      gtk_widget_show (answer3text);
      gtk_container_add (GTK_CONTAINER (answer3), answer3text);
      gtk_label_set_line_wrap (GTK_LABEL (answer3text), TRUE);
    
      answer4 = gtk_check_button_new ();
      gtk_widget_show (answer4);
      gtk_box_pack_start (GTK_BOX (vbox2), answer4, TRUE, TRUE, 5);
      gtk_widget_add_accelerator (answer4, "clicked", accel_group,
                                  GDK_4, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      answer4text = gtk_label_new ("Antwort 4");
      gtk_widget_show (answer4text);
      gtk_container_add (GTK_CONTAINER (answer4), answer4text);
      gtk_label_set_line_wrap (GTK_LABEL (answer4text), TRUE);
    
      hbuttonbox2 = gtk_hbutton_box_new ();
      gtk_widget_show (hbuttonbox2);
      gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox2, FALSE, FALSE, 0);
      gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox2), GTK_BUTTONBOX_SPREAD);
    
      btnExit = gtk_button_new ();
      gtk_widget_show (btnExit);
      gtk_container_add (GTK_CONTAINER (hbuttonbox2), btnExit);
      GTK_WIDGET_SET_FLAGS (btnExit, GTK_CAN_DEFAULT);
      gtk_widget_add_accelerator (btnExit, "clicked", accel_group,
                                  GDK_BackSpace, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      alignment2 = gtk_alignment_new (0.5, 0.5, 0, 0);
      gtk_widget_show (alignment2);
      gtk_container_add (GTK_CONTAINER (btnExit), alignment2);
    
      hbox3 = gtk_hbox_new (FALSE, 2);
      gtk_widget_show (hbox3);
      gtk_container_add (GTK_CONTAINER (alignment2), hbox3);
    
      image2 = gtk_image_new_from_stock ("gtk-stop", GTK_ICON_SIZE_BUTTON);
      gtk_widget_show (image2);
      gtk_box_pack_start (GTK_BOX (hbox3), image2, FALSE, FALSE, 0);
    
      label2 = gtk_label_new_with_mnemonic ("Abbrechen");
      gtk_widget_show (label2);
      gtk_box_pack_start (GTK_BOX (hbox3), label2, FALSE, FALSE, 0);
    
      btnBack = gtk_button_new ();
      gtk_widget_show (btnBack);
      gtk_container_add (GTK_CONTAINER (hbuttonbox2), btnBack);
      GTK_WIDGET_SET_FLAGS (btnBack, GTK_CAN_DEFAULT);
      gtk_widget_add_accelerator (btnBack, "clicked", accel_group,
                                  GDK_KP_Left, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      alignment1 = gtk_alignment_new (0.5, 0.5, 0, 0);
      gtk_widget_show (alignment1);
      gtk_container_add (GTK_CONTAINER (btnBack), alignment1);
    
      hbox2 = gtk_hbox_new (FALSE, 2);
      gtk_widget_show (hbox2);
      gtk_container_add (GTK_CONTAINER (alignment1), hbox2);
    
      image1 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_BUTTON);
      gtk_widget_show (image1);
      gtk_box_pack_start (GTK_BOX (hbox2), image1, FALSE, FALSE, 0);
    
      label1 = gtk_label_new_with_mnemonic ("Zur\303\274ck");
      gtk_widget_show (label1);
      gtk_box_pack_start (GTK_BOX (hbox2), label1, FALSE, FALSE, 0);
    
      btnForward = gtk_button_new_from_stock ("gtk-go-forward");
      gtk_widget_show (btnForward);
      gtk_container_add (GTK_CONTAINER (hbuttonbox2), btnForward);
      GTK_WIDGET_SET_FLAGS (btnForward, GTK_CAN_DEFAULT);
      gtk_widget_add_accelerator (btnForward, "clicked", accel_group,
                                  GDK_KP_Right, (GdkModifierType) 0,
                                  GTK_ACCEL_VISIBLE);
    
      g_signal_connect ((gpointer) wndQuestions, "destroy",
                        G_CALLBACK (on_wndQuestions_destroy),
                        NULL);
      g_signal_connect ((gpointer) btnForward, "clicked",
                        G_CALLBACK (on_btnForward_clicked),
                        NULL);
    
      /* Store pointers to all widgets, for use by lookup_widget(). */
      GLADE_HOOKUP_OBJECT_NO_REF (wndQuestions, wndQuestions, "wndQuestions");
      GLADE_HOOKUP_OBJECT (wndQuestions, vbox1, "vbox1");
      GLADE_HOOKUP_OBJECT (wndQuestions, hbox4, "hbox4");
      GLADE_HOOKUP_OBJECT (wndQuestions, scrolledwindow1, "scrolledwindow1");
      GLADE_HOOKUP_OBJECT (wndQuestions, treeview3, "treeview3");
      GLADE_HOOKUP_OBJECT (wndQuestions, vbox2, "vbox2");
      GLADE_HOOKUP_OBJECT (wndQuestions, category, "category");
      GLADE_HOOKUP_OBJECT (wndQuestions, hbox4, "hbox4");
      GLADE_HOOKUP_OBJECT (wndQuestions, image3, "image3");
      GLADE_HOOKUP_OBJECT (wndQuestions, question, "question");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer1, "answer1");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer1text, "answer1text");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer2, "answer2");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer2text, "answer2text");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer3, "answer3");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer3text, "answer3text");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer4, "answer4");
      GLADE_HOOKUP_OBJECT (wndQuestions, answer4text, "answer4text");
      GLADE_HOOKUP_OBJECT (wndQuestions, hbuttonbox2, "hbuttonbox2");
      GLADE_HOOKUP_OBJECT (wndQuestions, btnExit, "btnExit");
      GLADE_HOOKUP_OBJECT (wndQuestions, alignment2, "alignment2");
      GLADE_HOOKUP_OBJECT (wndQuestions, hbox3, "hbox3");
      GLADE_HOOKUP_OBJECT (wndQuestions, image2, "image2");
      GLADE_HOOKUP_OBJECT (wndQuestions, label2, "label2");
      GLADE_HOOKUP_OBJECT (wndQuestions, btnBack, "btnBack");
      GLADE_HOOKUP_OBJECT (wndQuestions, alignment1, "alignment1");
      GLADE_HOOKUP_OBJECT (wndQuestions, hbox2, "hbox2");
      GLADE_HOOKUP_OBJECT (wndQuestions, image1, "image1");
      GLADE_HOOKUP_OBJECT (wndQuestions, label1, "label1");
      GLADE_HOOKUP_OBJECT (wndQuestions, btnForward, "btnForward");
    
      gtk_window_add_accel_group (GTK_WINDOW (wndQuestions), accel_group);
    
      return wndQuestions;
    }
    


  • Hm, erwartest du, dass wenn du das GtkWindow größer ziehst, dass dann der gleiche Text in den Labels ebenfalls in die Breite geht?



  • Der Text soll ned unbedingt breiter werden *g* Er soll nur den verfügbaren Platz nutzen (der Textbereich soll breiter werden).
    Mir würds ja schon reichen, wenn sich der Text anpasst, wenn ich den Text später nochmal veränder (also ich den Inhalt veränder).



  • Okay, ich hab mich mal hingesetzt und 'n kleines Beispielprogramm geschrieben. Kompilier es und drück ein paar mal auf den "OK" Button.
    Sieht für mich alles sehr normal aus, das GtkWindow wird größer, wenn größerer Text im GtkLabel angezeigt werden soll. Und wenn wieder kleinerer drin steht, kann man's auch wieder kleiner machen.

    #include <gtk/gtk.h>
    
    /* Ein paar Testausgaben */
    static gchar *array[] = { "This is short",
    			  "But this is a real looooooooooong one",
    			  "I'm just between the other two",
    			  "Look at me, I'll stretch the window once more ;-)",
    			  "And I'm even\nmultiline"
    };
    
    /* Unsere Applikation. Enthält einige Gtk-Komponenten*/
    typedef struct {
      GtkWidget *button, *label, *vbox, *window;  
    } Application;
    
    Application *app;
    
    /* Die zwei Signal-Funktionen */
    static void destroy(GtkWidget *w, gpointer data) {
      gtk_main_quit();
    }
    
    static void clicked(GtkWidget *widget, gpointer data) {
      static int i = 0;
      if (i > 4)
        i = 0;
    
      gtk_label_set_text(GTK_LABEL(app->label), array[i++]);
    }
    
    int main(int argc, char **argv) {
      gtk_init(&argc, &argv);
    
      app = malloc(sizeof(Application));
    
      /* GtkButton initalisieren */
      app->button = gtk_button_new();
      gtk_button_set_label(GTK_BUTTON(app->button), "OK");
    
      /* GtkLabel initalisieren */
      app->label = gtk_label_new("Click the button");
      gtk_label_set_single_line_mode(GTK_LABEL(app->label), FALSE);
    
      /* GtkVBox mit GtkButton und GtkLabel initalisieren */
      app->vbox = gtk_vbox_new(FALSE, 20);
    
      gtk_container_add(GTK_CONTAINER(app->vbox), app->button);
      gtk_container_add(GTK_CONTAINER(app->vbox), app->label);
    
      app->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title(GTK_WINDOW(app->window), "Test");
    
      /* GtkVBox zum GtkWindow hinzufügen */
      gtk_container_add(GTK_CONTAINER(app->window), app->vbox);
    
      /* Signal-Handler setzen */
      g_signal_connect(G_OBJECT(app->window),"destroy", G_CALLBACK(destroy), NULL);
      g_signal_connect(G_OBJECT(app->button),"clicked", G_CALLBACK(clicked), NULL);
    
      /* Und los geht die wilde Fahrt 'trööt' */
      gtk_widget_show_all(app->window);
    
      gtk_main();
    
      free(app);
    
      return 0;
    }
    


  • Ein kleines Detail stell ich mir anders vor: GTK übernimmt für mich das umbrechen vom Text, was bei deiner Variante ja händisch gemacht wird.

    Trotzdem danke für deine Bemühungen 👍



  • Mekl schrieb:

    Ein kleines Detail stell ich mir anders vor: GTK übernimmt für mich das umbrechen vom Text, was bei deiner Variante ja händisch gemacht wird.

    Dann musst du das Label in der horizontalen fixieren, damit es nach unten wachsen kann. Halte ich aber für einen schlechten Ansatz, da du so den Layout-Manager aushebelst und es evtl. zu unschönen Effekten kommen kann. Also bitte lassen 🙂


Log in to reply