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

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2009
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 272
    Points : 100
    Points
    100
    Par défaut Programme c et sqlite3 : récupérer valeur d'un enregistrement pour l'envoyer dans un champ texte interface gtk
    Bonjour, brève explication de mon problème :

    J'ai un programme en c qui lance une interface GTK+ avec divers boutons, champs texte....
    Ce programme travaille avec une base de donnée sqlite3.

    Je veux récupérer la valeur d'un seul (j'insiste bien sur le "un seul") enregistrement à l'aide d'une requête : "SELECT (MonChamp) FROM MaTable;".
    De plus j'ai besoin de le récupérer sous forme de chaîne de caractères car je dois l'envoyer ensuite dans un champ texte de mon interface GTK+.

    J'ai fouillé sur internet pour trouver une solution et la plupart du temps on conseil d'utiliser la fonction "callback". Cette fonction fait un affichage de plusieurs enregistrements (ça c'est pas un problème, en bidouillant on peut sélectionner un unique enregistrement) et elle retourne un entier, pas une chaîne de caractère. Je ne peux donc pas l'utiliser pour envoyer mon enregistrement dans un champ texte de l'interface.

    Suis-je passé à côté de quelque chose ?

    Voici mon code pour plus de clarté :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include "sqlite3.h"
     
    //FUNCTIONS
     
    static int callback(void *data, int argc, char **argv, char **azColName){
    	int i;
    	fprintf(stderr, "%s: ", (const char*)data);
    	for(i=0; i<argc; i++){
    		printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    	}
    	printf("\n");
    	return 0;
    }
     
    static void
    print_hello (GtkWidget *widget,
                 gpointer   data)
    {
      g_print ("Hello World\n");
    }
     
    int main(int argc,char *argv[])
    {
    	//GTK
    	GtkBuilder *builder;
    	GObject *mainWindow;
    	GObject *button;
    	GObject *entry;
     
    	//SQLITE3
    	sqlite3 *db=NULL;
    	int rc;
     
    	//Open database
    	rc = sqlite3_open("test.db", &db);
    	if(rc)
    		{
    			fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));
    			exit(0);
    		}
    	else
    		{
    			fprintf(stderr,"Opened database successfully\n");
    		}
     
    	gtk_init(&argc,&argv);
     
    	// Construct a GtkBuilder instance and load our UI description
    	builder=gtk_builder_new();
    	gtk_builder_add_from_file(builder,"test.ui",NULL);
     
    	//Connect signal handlers to the constructed widgets
    	mainWindow=gtk_builder_get_object(builder,"mainWindow");
    	g_signal_connect(mainWindow,"destroy",G_CALLBACK(gtk_main_quit),NULL);
     
    	//Buttons
    	button=gtk_builder_get_object(builder,"buttonTest");
    	g_signal_connect(button,"clicked",G_CALLBACK(print_hello),NULL);
     
     
    	//Entries
    	entry=gtk_builder_get_object(builder,"entryTest");//mon champ texte
     
     
    	char *zErrMsg=0;
    	char sql[250]="";
    	const char *data = "";
     
    	snprintf(sql, 249,"SELECT (Description) FROM Fruits WHERE (Id) = 1;");//ma requête
     
    	rc=sqlite3_exec(db,sql,callback,(void*)data,&zErrMsg);
    	if(rc!=SQLITE_OK){
    		fprintf(stderr,"SQL error: %s\n",zErrMsg);
    		sqlite3_free(zErrMsg);
    	}else{
    		fprintf(stdout,"Operation done successfully\n");//la requête m'affiche le résultat dans le terminal
    	}
     
    	gtk_entry_set_text(GTK_ENTRY(entry),G_CALLBACK(callback));	//c'est ici que je veux envoyer la valeur de mon enregistrement dans mon champ texte
    														//j'obtient évidemment ce warning : main.c:82:2: warning: passing argument 2 of ‘gtk_entry_set_text’ from incompatible pointer type [enabled by default] ; /usr/include/gtk-3.0/gtk/gtkentry.h:176:12: note: expected ‘const gchar *’ but argument is of type ‘void (*)(void)’
     
     
    	gtk_main();
     
    	return 0;
    }
    Merci d'avance pour vos réponses.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Bonjour

    J'utilise pas sqlite en C (je l'utilise en Python). Mais en lisant cette page https://www.sqlite.org/c3ref/exec.html, il me semble que tu dois passer par sqlite3_exec(). La fonction de callback() (facultative) n'est pas faite pour renvoyer une valeur de ta base mais elle est appelée pour évaluer les lignes récupérées. Et si elle ne renvoie pas 0, la requête est annulée...

  3. #3
    Membre régulier
    Inscrit en
    Juillet 2009
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 272
    Points : 100
    Points
    100
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Mais en lisant cette page https://www.sqlite.org/c3ref/exec.html, il me semble que tu dois passer par sqlite3_exec().
    J'ai lu cette page et quelques autres du même site. Cela m'as mis sur la piste et en parcourant quelques forums anglophones je suis arrivé à ce que je veux.
    Cependant je n'ai pas utilisé la fonction sqlite3_exec() mais cela doit être possible avec aussi.

    Voici mon code qui fonctionne :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include "sqlite3.h"
    #include <string.h> //Fonctions strcpy, strcat
     
    //FUNCTIONS
     
    //Open database
    static sqlite3 *openDb(char *dbName)
    {
    	sqlite3 *db=NULL;
    	int rc;
     
    	rc=sqlite3_open(dbName, &db);
    	if(rc)
    		{
    			fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));
    			exit(0);
    		}
    	else
    		{
    			fprintf(stderr,"Opened database successfully\n");
    		}
    	return db;
    }
     
    //Close database
    static void closeDb(sqlite3 *db)
    {
    	sqlite3_close(db);
    	printf("Database closed");
    }
     
    static void
    print_hello (GtkWidget *widget,gpointer data)
    {
    	g_print ("Hello World\n");
    }
     
    int main(int argc,char *argv[])
    {
    	//GTK
    	GtkBuilder *builder;
    	GObject *mainWindow;
    	GObject *button;
    	GObject *entryText;
     
    	//SQLITE3
    	sqlite3 *db=NULL;
    	sqlite3_stmt *stmt;
    	char *dbName="test.db";
    	int rc;
    	char *sql="SELECT Description FROM Fruits WHERE Id=1";
    	char * description;
     
    	gtk_init(&argc,&argv);
     
    	//Entries
    	entryText=gtk_builder_get_object(builder,"entryFruitsDesignation");
     
    		//Open database
    	db=openDb(dbName);
     
    	/* prepare the sql, leave stmt ready for loop */
    	rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    	if (rc != SQLITE_OK) {
    		printf("Failed to prepare database\n\r");
    		sqlite3_close(db);
    		return 2;
    		}
     
    	printf("SQL prepared ok\n\r");
     
    	/* allocate memory for decsription and venue */
    	description = (char *)malloc(100);
     
    	/* loop reading each row until step returns anything other than SQLITE_ROW */
    	do {
    		rc = sqlite3_step(stmt);
    		if (rc == SQLITE_ROW) { //can read data
    			strcpy(description,(char *)sqlite3_column_text(stmt,0));//récupération de la valeur grâce à la requête
    			printf("Description : %s \n",description);
    		}
    	} while (rc == SQLITE_ROW);
     
    	gtk_entry_set_text(entryText,description);//mise de la valeur récupérer dans le champ texte
     
    	/* finish off */
    	sqlite3_close(db);
    	free(description);
     
    	//Close database
    	closeDb(db);
     
    	gtk_main();
     
     
    	return 0;
    }
    Voici la page qui m'a mis sur la piste : https://www.sqlite.org/c3ref/stmt.html.
    Il faut plus ou moins respecter ces 5 étapes pour récupérer un enregistrement avec une requête SELECT.

    Merci pour m'avoir aiguillé !

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mat08 Voir le message
    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
    //Open database
    static sqlite3 *openDb(char *dbName)
    {
    	sqlite3 *db=NULL;
    	int rc;
    	
    	rc=sqlite3_open(dbName, &db);
    	if(rc)
    		{
    			fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));
    			exit(0);
    		}
    	else
    		{
    			fprintf(stderr,"Opened database successfully\n");
    		}
    	return db;
    }
    C'est pas bon de sortir d'une fonction par exit(). C'est trop brutal. Quand une fonction ne fait pas son travail on lui fait renvoyer une valeur spéciale que l'appelant récupère et gère. Quitte à renvoyer lui-aussi une valeur spéciale qui remontera lors de'appelant en appelant jusqu'au main. Lui seul est autorisé à faire exit() mais comme c'est la dernière fonction, autant faire un return.

  5. #5
    Membre régulier
    Inscrit en
    Juillet 2009
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 272
    Points : 100
    Points
    100
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    C'est pas bon de sortir d'une fonction par exit(). C'est trop brutal. Quand une fonction ne fait pas son travail on lui fait renvoyer une valeur spéciale que l'appelant récupère et gère. Quitte à renvoyer lui-aussi une valeur spéciale qui remontera lors de'appelant en appelant jusqu'au main. Lui seul est autorisé à faire exit() mais comme c'est la dernière fonction, autant faire un return.
    Ok, j'en prend note.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 02/04/2015, 11h58
  2. récupérer les dates de mysql et les mettre dans des champs textes
    Par abdelkarim_1987 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 18/10/2013, 15h56
  3. Réponses: 7
    Dernier message: 21/08/2013, 11h02
  4. Réponses: 7
    Dernier message: 28/10/2008, 11h54
  5. Réponses: 2
    Dernier message: 06/07/2007, 11h59

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