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 :

Raffraîchissement non effectué de l'interface graphique


Sujet :

GTK+ avec C & C++

  1. #1
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut Raffraîchissement non effectué de l'interface graphique
    Bonjour,

    Nous sommes un groupe de quatre personnes réalisant dans le cadre de notre troisième année de licence un projet de développement en C, utilisant la librairie graphique GTK+. Le sujet est la création d'un labyrinthe avec génération du labyrinthe, sa résolution automatique/incrémentale...

    Le projet a été rendu mais avec un problème assez conséquent... Nous n'arrivons pas à rafraichir le labyrinthe lorsqu'on souhaite en créer un, de même lorsque nous nous déplaçons.

    Nous avons utilisé (tenté d'utilisé ? ) la méthode de conception MVC pour réaliser cette application.

    Au niveau du modèle, tout se passe comme il le faut, il n'y a aucun problème... Nous avons simulé le labyrinthe sous le terminal et ça passe bien... C'est simplement au niveau de l'interface, au niveau de GTK que nous avons ce problème.


    Je vous remercie par avance du temps que vous passerez dessus...




    Dans l'archive rar jointe, vous trouverez le code intégral de l'application, ainsi que la documentation réalisée à l'aide de Doxygen.

    Pièce jointe 42718
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  2. #2
    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
    J'ai commencé à regarder votre code. Après que ma console est vomi une soixantaine de ligne d'erreurs, j'ai sorti le coupe-coupe et est commencé le défrichage en ligne .

    Première question : Dans interface.c j'ai des erreurs récurrentes sur le pointeur P dans la fonction void NewLabyrinthe(GtkWidget* widget, gpointer data); et dans d'autres. Ce pointeur n'est pas déclaré en global, c'est qui est bien, mais apparemment il n'est déclaré nul part!

    Un peu de lumière de ce côté me permettrai d'avancer.

  3. #3
    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
    autre exemple du problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void SolutionAutomatique(GtkWidget* widget, gpointer data)
    {
    	liste_coord * solution;
    	solution = SolutionTotale(P);
    	AffichageLabyrinthe(P, solution);
    }
    P? Je le prends où?

  4. #4
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut
    Veuillez m'excuser, j'ai du me tromper de version en la mettant dans une archive.

    Pièce jointe 42718

    Si toutes fois vous avez des erreurs de compilation... Je ne comprends pas... Des warnings cependant sont présent...

    Normalement, le code compile sous MAC, Windows et Linux.

    Je viens de le tester sous Code::Blocks
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  5. #5
    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
    Bon, avec ce nouveau code ca compile. C'est déjà ca.

    Je vais y aller par étape. Pour commencer les premiers warnings de gcc. Dans la fonction void Score(GtkWidget* widget, gpointer data) on peut remplacer avantageusement les strcat et autres par une fonction de la glib bien utile :
    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
    void Score(GtkWidget* widget, gpointer data)
    {
        GtkWidget *pScore;
    //	char message1[50] = "\n Votre score est de : ";
    //	char message2[50] = "\n Votre nombre de coups est de : ";
    char *message1=NULL;
    //	char score[10];
    //	char coups[10];
    	int nb_score;
    	int nb_coups;
     
    	// On recupere le score et on l'affiche dans un message
    	nb_score = GetScore(P);
    /*	sprintf(score, "%d", nb_score);
    	strcat(message1,score);
    */
    	// On recupere le nombre de coups et on l'affiche dans un message
    	nb_coups = GetNbCoups(P);
    /*	sprintf(coups, "%d", nb_coups);
    	strcat(message2,coups);
     
    	strcat(message2,"\n");
    	strcat(message2,message1);
    */
    message1=g_strdup_printf("\n Votre score est de : %d\n Votre nombre de coups est de : %d\n",nb_score, nb_coups);
    	// Creation de la fenetre affichant le score et le nombre de coups
        pScore = gtk_message_dialog_new (GTK_WINDOW(data),
    									 GTK_DIALOG_MODAL,
    									 GTK_MESSAGE_INFO,
    									 GTK_BUTTONS_CLOSE,
    									 message1, NULL);
    g_free(message1);
    	// Si le score est egal a -1 alors le joueur na pas termner sa partie
    	// Si le score est différent de -1, on lui affiche son score t son nombre de coups
    	if (nb_score == -1){
    		gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (pScore), "<span foreground=\"red\"><b>\n       Vous n'avez pas terminé la partie!       </b></span>\n");
    	}
    	else{
    		message1=g_strdup_printf("\n Votre nombre de coups est de : %d", nb_coups);
    		gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (pScore), message1);
    		g_free(message1);
    	}
     
    	// On donne un titre à la fenetre
    	gtk_window_set_title(GTK_WINDOW(pScore), "Score");
     
    	// On affiche la fenetre
    	gtk_dialog_run(GTK_DIALOG(pScore));
     
    	// On detruit la fenetre
        gtk_widget_destroy(pScore);
    }
    Je poursuis ma lecture...

  6. #6
    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
    Histoire de vous faire avancer un peu, j'ai résolu pas mal de problèmes sans toutefois avoir fait complétement le tour. Il y a encore un problème lors du lancement du jeu, le labyrinthe ne s'affiche que lors du premier déplacement. Selon la direction l'image du personnage n'est pas chargée ce qui provoque un éclatement du labyrinthe etc... Cependant vous verrez votre labyrinthe, ce qui est déjà pas mal.

    Pour les modifs apportées elles sont tellement nombreuses que je ne peux pas les lister ici. Le principe est que pour mettre à jour la table pTable il faut d'abord la supprimer puis insérer la nouvelle à l'emplacement de l'ancienne. Ce qui implique d'avoir sous la main le pointeur de la vbox dans laquelle ce trouve la pTable ainsi que le pointeur de la pTable. J'ai donc modifié tout votre code en fonction de ce principe. Le tout sans déclaration en global bien sur.
    J'ai mis des commentaires pour vous expliquer comment j'ai procédé dans votre code source.

    N'hésitez pas à poser d'autres questions si besoin.

    P.S. : Ha oui, j'oubliais. Pour des raisons de commodité j'ai viré votre Makefile pour le remplacer par le mien. Mais ceci ne change rien au problème.

  7. #7
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut
    Hum...

    Nous étions plus dans l'optique de remplacer les images, une par une.

    avec les pixbuf ou encor les set_image.

    Bien que notre première approche était de supprimer la pTable pour ensuite la remplacer... Mais ça ne fonctionnait pas...

    Alors nous avons utilisé un subterfuge (du moins lors de la création du labyrinthe) qui consistait à refaire la fenêtre, lui passer le focus (ça se faisait seul) et de détruire l'ancienne fenêtre.

    Mais bon... Ca m'énervait de bricoler ainsi.
    Je n'aime pas le code sale et j'ai été obligée, nous avons été obligés, d'en faire pas mal...

    edit : ça me met mal à l'aise que l'on me vouvoie, et si l'on passait au tutoiement pour plus de commodité ?

    Merci pour vos modification, je suis en train d'étudier le code
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  8. #8
    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
    Oui je tutoivous sans probème. Heuu! oui ca va s'arranger

    L'idée la plus proche serait de créer un pixbuf du labyrinthe sur lequel on ajoute le perso et les marques de pas.

    Ca simplifierai grandement le code.

  9. #9
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut
    Un pixbuf est un objet contenant les données d'une image non ?

    Alors comment faire un pixbuf du labyrinthe ?
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  10. #10
    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
    Oui un pixbuf est une structure contenant la taille de l'image, le nombre d'octet par pixel et enfin un pointeur sur un tableau de données représentant la fameuse image.

    Alors comment faire?

    La librairie GdkPixbuf, inclue dans GTK+ te permet de manipuler plus ou moins facilement ce type d'objet.
    Pour reprendre le principe de ton code source tu peux charger directement dans un GdkPixbuf chaque portion d'image. Ensuite tu peux créer un GdkPixbuf vierge de la taille finale voulu. Il ne te reste ensuite plus qu'à copier, si on peut dire, dans ce pixbuf les portions d'images précédemment chargées.
    Malheureusement cette dernière opération n'est pas prévue par la librairie GdkPixbuf. C'est finalement le seul code qu'il faudra créer. Mais rien de très compliqué. Juste la manipulation de deux tableaux de guchar.

    Pour te donner un petit coup de pouce sur ce sujet je te mets en copie une fonction perso. pour accéder directement à un pixel quelconque d'un pixpuf. c'est déjà un début .

    Cette fonction te renvoie un pointeur sur le pixel choisi avec les coordonnées (x,y). En plus tu peux lui donner 4 pointeurs qui te renvoie les composantes couleurs ainsi que le canal alpha (s'il existe) de ce pixel. Si tu n'as pas besoin de ces composantes transmets la valeur NULL pour chacune d'elles.

    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
    guchar *gdk_pixbuf_get_pixels_by_coord (const GdkPixbuf *pixbuf, const gint x, const gint y, guchar *red, guchar *green, guchar *blue,	guchar *alpha)
    {
    	guchar *pixel=NULL;
    	guint32 rowstride=0;
     
    	if (!pixbuf)
    	{
    		fprintf(stderr,"Dans la fonction gdk_pixbuf_get_pixels_by_coord(); \
    pixbuf = NULL!\n");
    		return NULL;
    	}
    	if (x > gdk_pixbuf_get_width(pixbuf))
    	{
    		fprintf(stderr,"Dans la fonction gdk_pixbuf_get_pixels_by_coord(); x > à \
    la largeur de pixbuf!\n");
    		return NULL;
    	}
    	if (y > gdk_pixbuf_get_height(pixbuf))
    	{
    		fprintf(stderr,"Dans la fonction gdk_pixbuf_get_pixels_by_coord(); y > à \
    la hauteur of pixbuf!\n");
    		return NULL;
    	}
     
    	pixel=gdk_pixbuf_get_pixels(pixbuf);
    	rowstride=gdk_pixbuf_get_n_channels(pixbuf)*y*gdk_pixbuf_get_width(pixbuf);
    	if (red)
    		*red = pixel[(gdk_pixbuf_get_n_channels(pixbuf)*x)+rowstride];
    	if (green)
    		*green = pixel[(gdk_pixbuf_get_n_channels(pixbuf)*x)+rowstride+1];
    	if (blue)
    		*blue = pixel[(gdk_pixbuf_get_n_channels(pixbuf)*x)+rowstride+2];
    	if (alpha && gdk_pixbuf_get_has_alpha(pixbuf))
    		*alpha = pixel[(gdk_pixbuf_get_n_channels(pixbuf)*x)+rowstride+3];
     
    	return &pixel[(gdk_pixbuf_get_n_channels(pixbuf)*x) + rowstride];
    }

  11. #11
    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 rectifie ce que je viens d'écrire. Hormis la fonction que peut toujours être utile il existe tout de même une fonction permettant de copier directement une portion d'un pixbuf dans un autre :
    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
    void                gdk_pixbuf_copy_area                (const GdkPixbuf *src_pixbuf,
                                                             int src_x,
                                                             int src_y,
                                                             int width,
                                                             int height,
                                                             GdkPixbuf *dest_pixbuf,
                                                             int dest_x,
                                                             int dest_y);
     
    Copies a rectangular area from src_pixbuf to dest_pixbuf. Conversion of pixbuf formats is done automatically.
     
    If the source rectangle overlaps the destination rectangle on the same pixbuf, it will be overwritten during the copy operation. Therefore, you can not use this function to scroll a pixbuf.
     
    src_pixbuf :
    	Source pixbuf.
     
    src_x :
    	Source X coordinate within src_pixbuf.
     
    src_y :
    	Source Y coordinate within src_pixbuf.
     
    width :
    	Width of the area to copy.
     
    height :
    	Height of the area to copy.
     
    dest_pixbuf :
    	Destination pixbuf.
     
    dest_x :
    	X coordinate within dest_pixbuf.
     
    dest_y :
    	Y coordinate within dest_pixbuf.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 26/12/2006, 15h17
  2. [Avis] Interfaces graphiques à la main ou non ?
    Par pugnator dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 11/09/2005, 18h45
  3. Application multiplateforme avec interface graphique
    Par TNorth dans le forum Choisir un environnement de développement
    Réponses: 2
    Dernier message: 31/01/2004, 18h55
  4. [Kylix] Interface graphique pour lognes de commande linux
    Par lecharcutierdelinux dans le forum EDI
    Réponses: 6
    Dernier message: 29/08/2003, 10h20
  5. plugin interface graphique
    Par jocelyn dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 13/08/2003, 09h49

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