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+ avec C & C++ Discussion :

Problème d'onglet


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Par défaut Problème d'onglet
    Bonjour je désirerai réaliser un éditeur de fichier CSS et j'ai actuellement un petit problème de gestion de mes onglets je vous explique. J'Utilise une liste doublement chaînée GList pour gérer mes onglets mais le problème ne viens pas de là.
    Pour fermer mes onglets j'essaie d'avoir un bouton de fermeture en haut de l'onglet actif. Lorsque je crée un nouvel onglet le bouton de fermeture de l'onglet précédent est caché et j'affiche le bouton de fermeture sur le nouvel onglet actif.

    Ainsi seul l'onglet actif possède un bouton de fermeture d'onglet. Mon problème est que lorsque je change d'onglet j'arrive pas à gérer ça. Il me fait apparaitre le bouton de fermeture sur le bouton que j'avais précédemment sélectionné.

    Ex : Je suis sur l'onglet 3 je passe sur le 2 rien ne change, je passe sur le 1 il me fait apparaitre le bouton de fermeture sur l'onglet 2.

    Trêve de blabla je vous montre mes fonctions :

    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
     
    /// Fonction d'ajout d'un autre onglet
     
    void add_notebook(GtkWidget *widget, Fenetre *window)
    {
     
        if(window->doc->ouvert==0)
        {
            window->doc->tous = NULL;
        }
     
        onglet *nouveau = NULL;
        onglet * onglet_precedent = NULL;
        nouveau = malloc(sizeof(onglet));
        nouveau->nom = NULL;
        nouveau->sauve = TRUE;
        gchar *nom_onglet = NULL;
     
        /// Création d'une box pour contenir le titre de l'onglet et le bouton de fermeture
     
        nouveau->onglet_box = gtk_hbox_new (FALSE, 0);
        nom_onglet = g_strdup_printf("Nouveau Document %d",window->doc->ouvert);
        nouveau->label = gtk_label_new (nom_onglet);
        gtk_box_pack_start (GTK_BOX (nouveau->onglet_box), nouveau->label, TRUE, TRUE, 0);
        nouveau->bouton = gtk_button_new ();
        nouveau->image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
        gtk_button_set_image (GTK_BUTTON (nouveau->bouton), nouveau->image);
        gtk_button_set_relief (GTK_BUTTON (nouveau->bouton), GTK_RELIEF_NONE);
        gtk_box_pack_start (GTK_BOX (nouveau->onglet_box), nouveau->bouton, TRUE, TRUE, 0);
     
        /// Ajout du nouvel onglet dans la liste doublement chainée
     
        window->doc->tous = g_list_append(window->doc->tous, nouveau);
        nouveau->fenetre_scrollable = gtk_scrolled_window_new (NULL, NULL);
        nouveau->zone_texte = GTK_TEXT_VIEW (gtk_text_view_new ());
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (nouveau->fenetre_scrollable), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
        nouveau->buffer = gtk_text_view_get_buffer (nouveau->zone_texte);
     
        gtk_container_add (GTK_CONTAINER (nouveau->fenetre_scrollable), GTK_WIDGET (nouveau->zone_texte));
        nouveau->label = gtk_label_new("Nouveau document");
        window->doc->index = gtk_notebook_append_page (window->doc->onglet, nouveau->fenetre_scrollable, nouveau->onglet_box);
     
        gtk_widget_show_all(nouveau->onglet_box);
        gtk_widget_show_all(GTK_WIDGET(window->doc->onglet));
        gtk_notebook_set_current_page (window->doc->onglet, window->doc->index);
     
        /// Positionnement sur l'ancien onglet pour cacher le bouton de fermeture
     
        onglet_precedent = g_list_nth_data(window->doc->tous,window->doc->precedent);
        if(onglet_precedent != NULL)
            {
                gtk_widget_hide(onglet_precedent->bouton);
            }
        window->doc->precedent = window->doc->index;
     
        window->doc->ouvert++;
     
        g_signal_connect (G_OBJECT (nouveau->bouton), "clicked", G_CALLBACK (fermer_onglet), window);
        g_signal_connect (G_OBJECT (window->doc->onglet), "switch-page", G_CALLBACK(switch_onglet), window);
     
    }
    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
     
    void switch_onglet(GtkNotebook *notebook,GtkNotebookPage *page,guint page_num,Fenetre *window)
    {
     
        onglet *onglet_precedent = NULL;
        onglet_precedent = g_list_nth_data(window->doc->tous, window->doc->precedent);
        if(onglet_precedent != NULL)
            {
                //printf("\nOK\n");
                gtk_widget_hide(onglet_precedent->bouton);
            }
        window->doc->precedent = gtk_notebook_get_current_page(window->doc->onglet);
        printf("\nnouvel onglet courant : %d\n",window->doc->precedent);
     
        onglet_precedent = NULL;
     
        onglet_precedent = g_list_nth_data(window->doc->tous, window->doc->precedent);
        if(onglet_precedent != NULL)
            {
                gtk_widget_show_all(onglet_precedent->bouton);
            }
     
    }

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    L'ajout de printf de ci de la pour afficher les valeurs de variables bien choisies me parait etre une bonne premiere etape pour tenter de comprendre ce que fait ton programme et pour mieux délimiter la partie fautive.
    NB: la fonction g_list_nth_data est très peu efficace, quand tu te retrouves à l'utiliser sans cesse comme c'est le cas dans ton code, c'est généralement indicateur d'un pb quelque part, ie soit le code pourrait être simplifié, soit les listes ne sont pas adaptées à ce que tu essaies de faire

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Par défaut
    Ce que je ne comprends pas cette méthode est censé me permette d'effacer le bouton fermer du nouvel onglet actif. Le signal switch-page est activé également lorsque je crée un nouvel onglet à chaque fois que je crée un nouvel onglet j'ai un passage de plus dans la fonction que dois éxécuté switch-page.

    Pour g_list_nth_data() il me semble ne pas trop avoir le choix que de l'utilisé vu que tout est stocké dans ma GList comment pourrais je récupérer mes données sinon !!

    En gros la vrai question est lorsque je change d'onglet en cliquant volontairement sur un autre onglet quel est le signal le plus adapté !!!

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Dans ton callback, t'as 2 facons de recuperer un numero de page, a l'aide du parametre page_num et en faisant gtk_notebook_get_current_page
    T'as vérifié que chaque fois que tu utilises une de ces 2 valeurs, elle a bien la valeur que tu souhaites ? ( a l'aide de printf)
    Une GList, c'est adapté à un parcours séquentiel, c'est a dire tu pars du début et tu regardes les éléments dans l'ordre ou tu les as stockes dans ta liste. Par contre, ca n'est pas du tout adapte a une utilisation du type "je veux acceder a l'element N" (pour des raisons de performances). Quand tu te retrouves a faire ca, c'est generalement le signe qu'un tableau alloue dynamiquement (par exemple) serait plus adapte a ton utilisation

  5. #5
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2006
    Messages
    287
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2006
    Messages : 287
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    Une GList, c'est adapté à un parcours séquentiel, c'est a dire tu pars du début et tu regardes les éléments dans l'ordre ou tu les as stockes dans ta liste. Par contre, ca n'est pas du tout adapte a une utilisation du type "je veux acceder a l'element N" (pour des raisons de performances). Quand tu te retrouves a faire ca, c'est generalement le signe qu'un tableau alloue dynamiquement (par exemple) serait plus adapte a ton utilisation
    Je suis d'accord sur la première partie 'une liste chainée est adaptée à un parcours séquentiel', en revanche conseiller l'utilisation d'un tableau allouée dynamiquement, ça se discute.
    Dans un tableau, pour supprimer ou insérer un élément, c'est tout un cirque (on ne discute pas de l'algo puisque les opérations sont de toutes façons plus couteuses en temps CPU), tandis que dans une liste chainée ces deux opérations sont grandement simplifiées (affectation d'une adresse)

    Ensuite, c'est au choix du développeur de savoir sur quels points il souhaite mettre l'accent : soit assurer des performances, soit se simplifier la vie, quitte à sacrifier un petit peu de performances.
    De plus, sur un programme de cette envergure, les données manipulées ne sont pas suffisamment importantes (en espace mémoire) pour que l'utilisation de l'une ou l'autre des solutions montre de réels écarts en terme de perfs.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Par défaut
    Merci en fait fallait utilisé page_num qui est transmis dans l'en tete de la fonction je réfléchi a ton idée de tableau mais l'ennui c'est que cela fonctionne bien avec la liste chainée et que la suppression est bien plus facile avec les fonctions glib sur les liste doublement chainée que sur un tableau classique même si c'est loin detre insurmontable lool !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème : un onglet disparaît
    Par LMA dans le forum MFC
    Réponses: 5
    Dernier message: 21/07/2006, 07h39
  2. problème : un onglet disparaît
    Par LMA dans le forum VC++ .NET
    Réponses: 0
    Dernier message: 19/07/2006, 14h27
  3. Probléme d'onglet
    Par jojo57 dans le forum Access
    Réponses: 3
    Dernier message: 27/04/2006, 15h49
  4. [CSS] Problème avec onglets
    Par jehlg dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 28/03/2006, 11h15
  5. [ONGLET]Problème d'onglet
    Par jaymz dans le forum IHM
    Réponses: 3
    Dernier message: 18/04/2005, 15h09

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