IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ Discussion :

Faut-il utiliser Glade avec GTK3 ?


Sujet :

GTK+

  1. #21
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    D'accord merci du rappel tu m'as bien éclairé !

    Maintenant je n’arrive toujours pas à résoudre mon problème...

    Tout d'abord, je déduis que je n'ai pas besoin de mallocs puisque je n'utiliserai pas mon RegistInfo info après que ma fonction createAccount soit fermée.
    Ensuite addBuilderFromGlade marche très bien partout dans mon code, je l'ai déjà utilisé sans soucis et dans mon cas actuel j'arrive bien à récupérer la windowRegister donc il n'y a pas de soucis à ce niveau là.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void createAccount()//creation dun nouveau compte
    {
        GtkBuilder *builder;
        GtkWidget *windowRegister;
        GtkWidget *button;
        RegistInfo info;
        builder = gtk_builder_new();
        addBuilderFromGlade(builder,"userRegister.glade");
        info.builder = builder;
        button = GTK_WIDGET(gtk_builder_get_object(builder,"confirmRegister"));
        windowRegister = GTK_WIDGET(gtk_builder_get_object(builder,"windowRegister"));
        g_signal_connect(windowRegister,"destroy",G_CALLBACK(gtk_main_quit),NULL);
        g_signal_connect(button,"clicked",G_CALLBACK(getInfoToRegister),&info);
        g_object_unref(builder);
        gtk_widget_show(windowRegister);
    }
    J'ai même vérifié que tous les paramètres que je transmets dans les fonctions que j'ai évoqué dans mon poste précédent sont bons et oui pour moi ils le sont.

    Pour rappel, j'initialise et lie mon builder au fichier glade, cela marche bien.
    Ensuite, je mets ce builder dans info.builder car j'en ai besoin dans les autres fonctions.
    J'envoie donc l'adresse de info à ma fonction getInfoToRegister qui reçoit &info à l'aide d'un pointeur RegistInfo *info.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void getInfoToRegister(GtkButton *button,RegistInfo *info)
    {
        info->name = getTextOfEntry(GTK_BUILDER(info->builder),"entryRegisterName");
    }
    Ce que je veux est récupérer le texte d'un entry et le ranger dans info->name donc j'appelle ma fonction getTextOfEntry dans laquelle je passe mon builder avec info->builder et c'est là que les choses se compliquent apparemment car j'ai toujours la même erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char *getTextOfEntry(GtkBuilder *builder,char *nameObject)
    {
        char *text;
        GtkWidget *entry;
        entry = GTK_WIDGET(gtk_builder_get_object(builder,nameObject));
        text = gtk_entry_get_text(GTK_ENTRY(entry));
        return text;
    }
    N'y a-t-il pas quelque chose de choquant dans ce que je fais ?

    Merci.

  2. #22
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Non rien n'est choquant.

    Mais il y a un mais .

    Dans la fonction createAccount(); tu crées une variable RegistInfo info. Il peut te sembler que info existe lors de l'appel à getInfoToRegister(); mais en réalité il n'en est rien.
    Dans createAccount(); tu indiques à la fonction getInfoToRegister(); d'utiliser l'adresse de info qui est une variable locale, donc initialisée dans la pile. Ta fonction se termine pour ensuite exécuter au final gtk_main ();.
    info n'existe plus ! Si tu veux conserver ton code il te faut allouer info dans le tas avec un petit malloc();.

  3. #23
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par JeremTer Voir le message
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char *getTextOfEntry(GtkBuilder *builder,char *nameObject)
    {
        char *text;
        GtkWidget *entry;
        entry = GTK_WIDGET(gtk_builder_get_object(builder,nameObject));
        text = gtk_entry_get_text(GTK_ENTRY(entry));
        return text;
    }
    Pour être puriste le prototype de cette fonction pourrait être un peu affiner.

    Tu renvoies une chaîne de caractèree renvoyée elle-même par gtk_entry_get_text();. D'après la documentation officielle cette chaîne est le contenu du GtkEntry. Elle ne doit pas être modifiée. C'est pour cette raison que gtk_entry_get_text (); retourne un const gchar*. Ta fonction doit retourner le même type.

    Ensuite tu transmets une chaîne de caractères nameObject. Vu que dans la fonction tu ne fais que lire cette chaîne tu devrais elle aussi la transmettre comme une constante.

    Le prototype devrait donc être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char *getTextOfEntry(GtkBuilder *builder, const char *nameObject)
    Ainsi, un futur utilisateur ne pourra pas modifier/désallouer la chaîne retournée et saura que la chaîne qu'il transmet ne sera pas modifiée.

  4. #24
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Ok je comprends mieux. Pour tout te dire, j'avais essayé avec des mallocs, mais le problème c'est que je faisais les free dans la fonction createAccount(); et en plus de ça le g_object_unref(builder) dedans aussi.

    J'ai donc corrigé ces erreurs et ça fonctionne ! En fait, je n'avais pas compris que la fonction createAccount se terminait pour exécuter gtk_main(); grosse erreur de ma part.

    Est-il d’ailleurs obligatoire de faire un g_object_unref de mon builder ?

    Merci encore !

  5. #25
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Tu poses une question pratiquement existentielle .

    Je vais essayer de faire une réponse la plus rigoriste qu'il soit.

    "Ce que tu crées, tu le détruis lorsque tu n'en plus besoin."

    En partant de là, c'est la démarche la plus saine et la plus rigoureuse qui soit lorsqu’on programme en C, voir en C++.

    Ceci dit, certains diront que puisque le GtkBuilder ne sert plus à rien lorsque l'application se termine, pas besoin de le désallouer. C'est aujourd'hui vrai. Le système d'exploitation est capable de récupérer la mémoire allouée par une application qui vient de finir, même si celle-ci n'a rien libéré du tout.

    Tout est dit, la balle est dans ton camp .

  6. #26
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Haha donc c'est pas obligatoire mais c'est rigoureux. Alors mon erreur n'est pas due à cela.

    Il semble y avoir un petit problème avec mes free, car tout se passe bien quand je ne fais pas de free mais quand j'appelle cette fonction à la fin de la fonction qui affiche les entries :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void registerFree(RegistInfo *info)
    {
        free(info->builder);
        free((char*)info->confirmPassword);
        free((char*)info->mail);
        free((char*)info->name);
        free((char*)info->password);
        free(info);
    }
    le programme m'affiche ce que je veux puis plante et se termine avec un status -1.

    Ça c'est ma fonction pour malloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    RegistInfo *registerMalloc()
    {
        RegistInfo *info;
        info = malloc(sizeof(RegistInfo));
        info->builder = malloc(sizeof(GtkBuilder));
        info->name = malloc(sizeof(const char) * 100);
        info->mail = malloc(sizeof(const char) * 100);
        info->password = malloc(sizeof(const char) * 100);
        info->confirmPassword = malloc(sizeof(const char) * 100);
        return info;
    }

  7. #27
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Il y a une erreur marquée en rouge dans cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    registInfo *registerMalloc()
    {
        RegistInfo *info;
        info = malloc(sizeof(RegistInfo));
        info->builder = malloc(sizeof(GtkBuilder));
        info->name = malloc(sizeof(const char) * 100);
        info->mail = malloc(sizeof(const char) * 100);
        info->password = malloc(sizeof(const char) * 100);
        info->confirmPassword = malloc(sizeof(const char) * 100);
        return info;
    }
    La fonction gtk_builder_new_from_file (); ou une de ses dérivées alloue la mémoire nécessaire.
    Ici, tu as donc une fuite mémoire. Le pointeur de cette première allocation que tu fais sera écrasé lors de l'appel à la fonction gtk_builder_new_from_file();.
    La bonne chose à faire ici est d'initialiser ce pointeur à NULL.

    Une petite remarque. Si tu es sûr de ne jamais dépasser 100 caractères pour tes chaînes de caractères, tu peux te passer d'une allocation dans le tas. Tu peux écrire simplement ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    registInfo *registerMalloc()
    {
        RegistInfo *info;
        info = malloc(sizeof(RegistInfo));
        info->builder = NULL;
         return info;
    }
    Avec comme structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct RegistInfo{
        GtkBuilder *builder;
        char name[101];
        char mail[101];
        char password[101];
        char confirmPassword [101];
    }RegistInfo;
    Tu remarqueras que j'ai fixé la taille à 101 et non 100. Je tiens compte du caractère '\0' de fin de chaîne. Ainsi tu pourras bien avoir 100 caractères + le caractère de fin.

    Ensuite, il ya aussi une erreur mais qui est une conséquence de ton allocation précédente dans la fonction registerFree(RegistInfo *info) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void registerFree(RegistInfo *info)
    {
        free(info->builder);
        free((char*)info->confirmPassword);
        free((char*)info->mail);
        free((char*)info->name);
        free((char*)info->password);
        free(info);
    }
    La bonne chose à faire ici est un g_object_unref (info->builder);.

    Histoire de te montrer la variante avec une allocation locale des chaînes de caractères la fonction registerFree(RegistInfo *info); aurait cette tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void registerFree(RegistInfo *info)
    {
        g_object_unref (info->builder);
    }
    Ca se simplifie grandement .

    Maintenant venons-en à ton problème de plantage. Ton souci vient du fait que tu désalloues info->builder alors que ta fenêtre est toujours affichée et donc utilises toujours ce pointeur. La fonction registerFree(RegistInfo *info); doit être appelée après l'appel à la fonction gtk_main ();.
    Pour mémoire gtk_main (); lance une boucle. Lorsqu'elle se finit cela signifie que toutes les fenêtres sont fermées. On peut alors désallouer toute la mémoire avant de fermer l'application définitivement.

  8. #28
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Merci encore pour toutes ces précisions !

    Du coup si je veux free avec une fonction, je suis obligé de déclarer mon RegistInfo *info dans le main pour le faire passer à ma fonction freeRegist vu que mon gtk_main() est dans le main ?

    Car sinon je n'ai aucun moyen d'appeler le free après le gtk_main() alors que c'est mon but.

    S'il existe une autre solution ce serait bien, parce que je ne voudrais pas me retrouver avec un main de 3 pages quoi .

    Cordialement.

  9. #29
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Il me semble qu'on est un peu dans une incompréhension mutuelle .

    Alors comme un dessin (un exemple ici) vaut mieux qu'un long discours et comme c'est la période des fêtes je te donne un petit exemple de code le plus simple possible pour que tu vois directement l'agencement de tout ce petit monde.
    Pour cet exemple j'ai utilisé ta structure en initialisant un GtkBuilder. Je ne l'utilise pas n'ayant pas de fichier glade à fournir. Mais l'idée est de voir comment j'alloue dans le tas et surtout à quel moment je désalloue.
    J'utilise aussi une variable info du type de ta structure. Comme ca tu peux aussi voir qu'on peux se passer d'une allocation dans le tas. Comme info est alloué dans main(); cette variable existe tout au long de l'exécution de l'application.

    Remarque:
    Si tu veux désallouer en utilisant une fonction, il te suffit de remplacer g_object_unref (info.builder); par l'appel à ta fonction.


    N'hésite pas à continuer à poser des questions si tu as des interrogations.

    Code exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #include <stdlib.h>
    #include <gtk/gtk.h>
     
    typedef struct {
      GtkBuilder *builder;
      GtkWidget *label;
      char name [101];
      char mail [101];
      char password [101];
      char confirmPassword [101];
    }RegistInfo;
     
     
    static void
    cb_entry_activate (GtkEntry *entry, gpointer user_data)
    {
      RegistInfo *info = (RegistInfo*) user_data;
     
      /* Insertion du texte du GtkEntry dans le GtkLabel */
      gtk_label_set_text (GTK_LABEL (info->label), gtk_entry_get_text (entry));
    }
     
    gint
    main (gint argc, gchar *argv[])
    {
      GtkWidget *window = NULL;
      GtkWidget *box = NULL;
      GtkWidget *entry = NULL;
      RegistInfo info;
     
      /* init gtk */
      gtk_init(&argc, &argv);
     
      /* Initialisation du GtkBuilder pour l'exemple. Je ne charge pas de fichier
       * mais je crée tout de même un GtkBuilder. Il est donc alloué dans le tas
       * par la fonction de création.
       */
      info.builder = gtk_builder_new ();
     
      /* Création de la fenêtre principale */
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      /* gtk_window_set_default_size (GTK_WINDOW(window), 500, 300); */
     
      /* Création d'un GtkBox horizontal. Il contiendra un GtkEntry ainsi qu'un
       * GtkLabel dans lequel s'affichera le contenu du GtkEntry lors de la
       * validation du GtkEntry par la touche "Entrer".
       */
      box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
      gtk_container_add (GTK_CONTAINER (window), box);
     
      /* Création d'une entrée texte et insertion dans la box  */
      entry = gtk_entry_new ();
      gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 5);
     
      /* Création du GtkLabel et insertion dans la box */
      info.label = gtk_label_new ("");
      gtk_box_pack_start (GTK_BOX (box), info.label, FALSE, FALSE, 5);
     
      /* Signaux */
      g_signal_connect (G_OBJECT(window) , "destroy", G_CALLBACK (gtk_main_quit) , NULL);
      g_signal_connect (G_OBJECT(entry), "activate", G_CALLBACK (cb_entry_activate), &info);
     
      /* Affichage de la fenêtre */
      gtk_widget_show_all (window);
     
      /* Boucle principale de Gtk+ qui maintient l'affichage de la fenêtre */
      gtk_main ();
     
      /* À partir d'ici, la boucle a été interrompue par l'appel à gtk_main_quit();. La fenêtre est maintenant
       * fermée. On peut désallouer toute la mémoire du tas utilisée.
       */
     
      /* Libération mémoire du GtkBuilder */
      g_object_unref (info.builder);
     
      return EXIT_SUCCESS;
    }

  10. #30
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Rebonjour,

    merci de toujours pouvoir répondre à mes questions tout d'abord.

    Je vais essayer d'expliquer clairement ce que je veux .

    En réalité le bout de code avec mes fonctions createAccount etc correspondent à une création de compte dans mon application. Le truc c'est que quand on utilise mon application, on n'est pas obligé de créer un compte à chaque fois, jusqu'ici tout est normal.

    J'en déduit que le code dont je parle ne doit s'exécuter QUE si l'utilisateur a envie de créer un compte. C'est pour cela que dans mon main, je dis de lancer la fonction createAccount si on clique sur le boutton regist :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_signal_connect(regist, "clicked", G_CALLBACK(createAccount), NULL);
    Et si on ne clique pas, il n'y aurait aucun code qui viendrait "polluer" le main pour rien, c'était ça mon objectif de base.

    Maintenant je commence à penser que c'est trop prise de tête car si je déclare RegistInfo info dans le main, je n'aurai pas besoin de malloc ni de free, juste à passer &info dans mes fonctions et ça me semble plus simple.

    Que me recommandes-tu ?

    Merci.

  11. #31
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par JeremTer Voir le message
    ...
    Maintenant je commence à penser que c'est trop prise de tête car si je déclare RegistInfo info dans le main, je n'aurai pas besoin de malloc ni de free, juste à passer &info dans mes fonctions et ça me semble plus simple.

    Que me recommandes-tu ?

    Merci.
    Je te recommande exactement ta dernière remarque. Moins tu alloues dans le tas, plus ton programme est robuste et stable.

    Ca force à penser un peu l'agencement de ses données mais on y gagne à l'arrivée.

  12. #32
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Ok merci beaucoup.

    Une dernière petite question, je n'arrive pas à superposer deux images dans Glade, je suppose que tu sais comment faire ?

    Je voudrais juste que mes boutons soient sur la fenêtre principale.

    Cordialement.

  13. #33
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Je ne suis pas sûr de comprendre ce que tu veux faire.

    Si c'est placer deux boutons il te faut d'abord insérer un conteneur capable de contenir plusieurs GtkWidget enfants. Tu as à ta disposition GtkBox ou GtkGrid.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    GtkWindow
          |------------->GtkBox (par exemple)
                                    |-------------> GtkWidget (un bouton)
                                    |-------------> GtkWidget (un bouton)
    Regarde l'exemple que je t'ai donné c'est exactement ca que j'ai fait.

  14. #34
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    En gros je veux juste mettre une image de fond et placer tous mes widgets sur cette image. Le problème est que quand je mets des boutons avec la box, ils sont collés à l'image et non dessus.

    Dans l'exemple que tu as donné, tu la mets où l'image ? Parce que si je suis ton exemple, ça me donne ça :

    Nom : Capture.PNG
Affichages : 123
Taille : 121,8 Ko

    On voit que les boutons ne sont pas sur l'image mais bien collés en bas.

  15. #35
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Au temps pour moi. Je n'avais pas saisi ta problématique.

    On touche à un autre problème. Il faut utiliser les CSS pour pouvoir arriver à tes fins.

    Je te donne le code exemple précédent avec les outils nécessaires à l'affichage d'une image en fond de la fenêtre principale.

    Voila ce que ca donne chez moi. Change le nom de l'image pour que ca fonctionne chez toi. Ensuite, pour les propriétés d'affichage il faut utiliser les capacités du format CSS.

    Nom : Capture d’écran_2018-12-22_14-27-08.png
Affichages : 125
Taille : 144,3 Ko

    Code source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    #include <stdlib.h>
    #include <gtk/gtk.h>
     
    typedef struct {
      GtkBuilder *builder;
      GtkWidget *label;
      char name [101];
      char mail [101];
      char password [101];
      char confirmPassword [101];
    }RegistInfo;
     
     
    static gboolean
    affect_css_to_widget (GtkWidget *widget, const gchar *css)
    {
      g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
      g_return_val_if_fail (css!=NULL, FALSE);
     
      /* Ajout du css au widget */
      GtkCssProvider *CssProvider = gtk_css_provider_new ();
      GError *error = NULL;
     
      gtk_css_provider_load_from_data (CssProvider, css, -1, &error);
      if (error)
        {
          g_printerr ("%s\n", error->message);
          g_error_free (error);
          return FALSE;
        }
     
      GtkStyleContext *context = gtk_widget_get_style_context (widget);
      gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (CssProvider), GTK_STYLE_PROVIDER_PRIORITY_USER);
     
      g_object_unref (CssProvider);
     
      return TRUE;
    }
     
    static void
    cb_entry_activate (GtkEntry *entry, gpointer user_data)
    {
      RegistInfo *info = (RegistInfo*) user_data;
     
      /* Insertion du texte du GtkEntry dans le GtkLabel */
      gtk_label_set_text (GTK_LABEL (info->label), gtk_entry_get_text (entry));
    }
     
    gint
    main (gint argc, gchar *argv[])
    {
      GtkWidget *window = NULL;
      GtkWidget *box = NULL;
      GtkWidget *entry = NULL;
      RegistInfo info;
     
      /* init gtk */
      gtk_init(&argc, &argv);
     
      /* Initialisation d'une feuille de style CSS pour le fond de la fenêtre principale */
      gchar css [] = "window {\n\
        background-image : url(\"linux.jpg\");\n\
    }";
     
      /* Initialisation du GtkBuilder pour l'exemple. Je ne charge pas de fichier
       * mais je crée tout de même un GtkBuilder. Il est donc alloué dans le tas
       * par la fonction de création.
       */
      info.builder = gtk_builder_new ();
     
      /* Création de la fenêtre principale */
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_default_size (GTK_WINDOW(window), 500, 300);
     
      /* Ajout de la feuille de style à la fenêtre principale */
      if (!affect_css_to_widget (window, css))
          g_printerr ("problème d'insertion de la feuille de style à la fenêtre principale !\n");
     
      /* Création d'un GtkBox horizontal. Il contiendra un GtkEntry ainsi qu'un
       * GtkLabel dans lequel s'affichera le contenu du GtkEntry lors de la
       * validation du GtkEntry par la touche "Entrer".
       */
      box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
      gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
      gtk_container_add (GTK_CONTAINER (window), box);
     
      /* Création d'une entrée texte et insertion dans la box  */
      entry = gtk_entry_new ();
      gtk_widget_set_halign (entry, GTK_ALIGN_CENTER);
      gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
      gtk_box_pack_start (GTK_BOX (box), entry, TRUE, FALSE, 5);
     
      /* Création du GtkLabel et insertion dans la box */
      info.label = gtk_label_new ("");
      gtk_widget_set_halign (info.label, GTK_ALIGN_CENTER);
      gtk_widget_set_valign (info.label, GTK_ALIGN_CENTER);
      gtk_box_pack_start (GTK_BOX (box), info.label, FALSE, FALSE, 5);
     
      /* Signaux */
      g_signal_connect (G_OBJECT(window) , "destroy", G_CALLBACK (gtk_main_quit) , NULL);
      g_signal_connect (G_OBJECT(entry), "activate", G_CALLBACK (cb_entry_activate), &info);
     
      /* Affichage de la fenêtre */
      gtk_widget_show_all (window);
     
      gtk_main ();
     
      /* Libération mémoire du GtkBuilder */
      g_object_unref (info.builder);
     
      return EXIT_SUCCESS;
    }

  16. #36
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Waw ! Je n'aurais jamais pensé que ce serait aussi complexe.

    Du coup je vais être obligé de créer tout mes widgets à la main avec Gtk ?

    Merci beaucoup pour le code !

  17. #37
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Non. Tu peux très bien utiliser Glade.

    Ensuite, dans ton code source tu peux affecter une feuille de style à un widget particulier en récupérant son pointeur depuis le GtkBuilder.

  18. #38
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Ok merci pour tout c'est vraiment super gentil !

  19. #39
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    De rien. Si je peux aider tant mieux.

  20. #40
    Membre averti
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Novembre 2018
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2018
    Messages : 31
    Par défaut
    Le code ne marche pas chez moi, il m'affiche juste une fenêtre sans image de fond.

    J'ai juste enlever les GtkWidgets dans le code, je veux juste afficher l'image de fond sur la fenêtre pour l'instant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include "gtkFunctions.h"
     
    static gboolean
    affect_css_to_widget (GtkWidget *widget, const gchar *css)
    {
      g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
      g_return_val_if_fail (css!=NULL, FALSE);
     
      /* Ajout du css au widget */
      GtkCssProvider *CssProvider = gtk_css_provider_new ();
      GError *error = NULL;
     
      gtk_css_provider_load_from_data (CssProvider, css, -1, &error);
      if (error)
        {
          g_printerr ("%s\n", error->message);
          g_error_free (error);
          return FALSE;
        }
     
      GtkStyleContext *context = gtk_widget_get_style_context (widget);
      gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (CssProvider), GTK_STYLE_PROVIDER_PRIORITY_USER);
     
      g_object_unref (CssProvider);
     
      return TRUE;
    }
     
    gint
    main (gint argc, gchar *argv[])
    {
      GtkWidget *window = NULL;
      GtkWidget *box = NULL;
      GtkBuilder *builder = NULL;
      GtkWidget *entry = NULL;
     
      /* init gtk */
      gtk_init(&argc, &argv);
     
      /* Initialisation d'une feuille de style CSS pour le fond de la fenêtre principale */
      gchar css [] = "window {\n\
        background-image : url(\"img/beach.jpg\");\n\
    }";
     
      /* Initialisation du GtkBuilder pour l'exemple. Je ne charge pas de fichier
       * mais je crée tout de même un GtkBuilder. Il est donc alloué dans le tas
       * par la fonction de création.
       */
      builder = gtk_builder_new ();
      addBuilderFromGlade(builder,"test.glade");
      window = GTK_WIDGET(gtk_builder_get_object(builder,"window"));
     
      /* Ajout de la feuille de style à la fenêtre principale */
      if (!affect_css_to_widget (window, css))
          g_printerr ("problème d'insertion de la feuille de style à la fenêtre principale !\n");
     
      /* Signaux */
      g_signal_connect (G_OBJECT(window) , "destroy", G_CALLBACK (gtk_main_quit) , NULL);
     
      /* Affichage de la fenêtre */
      gtk_widget_show_all (window);
     
      gtk_main ();
     
      /* Libération mémoire du GtkBuilder */
      g_object_unref (builder);
     
      return EXIT_SUCCESS;
    }
    Cependant, je n'ai aucune erreur. J'ai vérifié le chemin de mon image de fond.

    Merci.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. [FAQ] Comment utiliser glade avec GtkBuilder ?
    Par Rachel dans le forum Contribuez
    Réponses: 2
    Dernier message: 01/11/2012, 12h55
  2. utiliser glade avec python sous windows
    Par sakura.sou dans le forum EDI/RAD
    Réponses: 1
    Dernier message: 25/07/2009, 09h31
  3. Réponses: 5
    Dernier message: 17/05/2007, 01h19
  4. Faut-il combiner Spring avec Struts ou utiliser Spring MVC ?
    Par micanti dans le forum Frameworks Web
    Réponses: 3
    Dernier message: 23/04/2007, 16h31
  5. [RegEx] Que faut-il utiliser avec l'UFT-8 : Regex ou POSIX ?
    Par Tchinkatchuk dans le forum Langage
    Réponses: 2
    Dernier message: 07/11/2006, 17h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo