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 :

[gtkmm] thread et protection des widget


Sujet :

GTK+

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut [gtkmm] thread et protection des widget
    bonjour,

    je souhaite utilisé un thread qui réactualise mon interface (un petit explorateur) mais je n'arrive pas à le faire sans synchroniser celui-ci par la fonction join() qui me fait perdre l'intérêt du thread.

    Sous gtk/gdk j'ai vu qu'il y avait les fonction gdk_thread_enter/leave mais sous gtkmm/gdkmm il n'y a rien d'équivalent.

    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
    void ListeCourant::listeDossierEff(void)
    {
    	static Glib::RefPtr<Gdk::Pixbuf> pixF=Gdk::Pixbuf::create_from_file(fen.getTheme()+ICON_FICHIER,TAILLE_ICON_PETITE,TAILLE_ICON_PETITE,true);
    	static Glib::RefPtr<Gdk::Pixbuf> pixD=Gdk::Pixbuf::create_from_file(fen.getTheme()+ICON_DOSSIER,TAILLE_ICON_PETITE,TAILLE_ICON_PETITE,true);
    	string repCourant=fen.getCourant();
    	try
    	{
    		Glib::Dir dir(repCourant);
     
    		string name=dir.read_name();
    		int id=0;
    		while(!name.empty())
    		{
    			if (name.length() && name[0] != '.')
    			{
    				string path=Glib::build_filename(repCourant,name);
     
    				Glib::ustring nom=Glib::filename_to_utf8(name);
    				if (Glib::file_test(path,Glib::FILE_TEST_IS_DIR))
    				{
    					TreeModel::Row row=*(this->refTreeModel->append());
    					row[this->treeModel.pixbuf]=pixD;
    					row[this->treeModel.chemin]=repCourant;
    					row[this->treeModel.nom]=nom;
    					row[this->treeModel.type]="Dossier";
    					row[this->treeModel.taille]="";
    					row[this->treeModel.id]=id++;
     
    					Dossier d(nom);
    					fen.getListeDossier().push_back(d);
    					fen.getListeDossier().sort(Dossier::tri);
    				}
    				else if (Glib::file_test(path,Glib::FILE_TEST_IS_REGULAR) && fichierTmp(path) && formatOK(path))
    				{
    					TreeModel::Row row=*(this->refTreeModel->append());
    					int taille=utile::taille(path);
    					Fichier f(fen.getCourant(),nom,taille);
    					if(f.getPixbuf())
    					{
    						f.setPixbufIconPetite(f.getPixbuf()->scale_simple(TAILLE_ICON_PETITE,TAILLE_ICON_PETITE,Gdk::INTERP_BILINEAR));
    						row[this->treeModel.pixbuf]=f.getPixbufIconPetite();
    					}
    					else
    						row[this->treeModel.pixbuf]=pixF;
     
    					row[this->treeModel.chemin]=repCourant;
    					row[this->treeModel.nom]=f.getNom();
    					row[this->treeModel.type]="Fichier";
    					if (taille<0)
    						row[this->treeModel.taille]="";
     
    					else if (taille/1048576>0)
    						row[this->treeModel.taille]=utile::all2string(taille/1048576)+","+utile::all2string(taille-(taille/1048576)*1048576)+" Mo";
    					else if (taille/1024>0)
    						row[this->treeModel.taille]=utile::all2string(taille/1024)+","+utile::all2string(taille-(taille/1024)*1024)+" ko";
    					else
    						row[this->treeModel.taille]=utile::all2string(taille)+" o";
     
    					row[this->treeModel.id]=id++;
     
    					fen.getListeFichier().push_back(f);
    					fen.getListeFichier().sort(Fichier::tri);
    				}
    			}
    			name=dir.read_name();
    			fen.getGLScene().queue_draw();
    		}
    		fen.getGLScene().queue_draw();
    	}
    	catch(const Glib::FileError& ex)
    	{
    		std::cout << ex.what() << std::endl;
    	}
    }
     
    void ListeCourant::liste(bool clear)
    {	
    	if (clear)
    		refTreeModel->clear();		
    	fen.supprimeListes();
     
    	if(!Glib::thread_supported())
    		Glib::thread_init();
     
    	try
    	{
    		thread=Glib::Thread::create(sigc::mem_fun(*this,&ListeCourant::listeDossierEff),true);
    		thread->join(); // ICI le join()
    	}
    	catch(Glib::ThreadError& e)
    	{
    		cout << e.what() << endl;
    	}
    	catch(Glib::Thread::Exit& e) {}
    }

  2. #2
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut
    j'ai essayé les foncitons :

    gdk_thread_enter/leave/flush() mais rien n'y fait. Je doit verrouiller un treeview mais je ne sais pas comment faire, un mutex ne suffit pas vu que le raffraichissement est automatique.

  3. #3
    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
    Tu peux pas faire en sorte d'appeler les fonctions gtk+ uniquemnet dans le thread principal ? Par ex en faisant tout le travail sauf l'affichage dans ton thread et en utilisant g_idle_add (ou une GAsyncQueue ou toute autre méthode plus appropriée en gtkmm) pour dire à ton thread principal "ok, il faut que tu affiches ça et ça" ?

  4. #4
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut
    en fait le thread remplacer un g_idle.

    Son intérêt est qu'il est fait en même temps que le programme principal tourne.

    Je liste les fichier d'un répertoire et je raffraichit le treeview en même temps (dans le thread). Je ne vois aps comment faire autrement.

  5. #5
    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
    Tu peux avoir un callback de g_idle_add qui sait ajouter une colonne à ton treeview par exemple. Comme ça tu fais les IOs dans un thread (j'imagine que cette partie là était lente donc que tu l'as déplacée) et les changements de treeview dans le thread principal (via le g_idle_add)

  6. #6
    Membre éclairé Avatar de Rniamo
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    508
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 508
    Par défaut
    c'est ce que je veux faire mais g_idle est lancer quand gtk ne fait rien, donc en fait il faudrait que je fasse un thread + g_idle ?

    edit :en fait je ne vois pas où mettre g_idle
    edit 2 : il n'y a pas moyen de rendre gtkmm thread-safe ?
    edit 3 :
    One common way to do this is to have non-GUI threads send requests to the GUI thread via a pipe. The pipe is hooked into the main glib event loop used by GTK.
    En clair ça veut dire quoi ?

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

Discussions similaires

  1. Gestion de l'état des widgets Tkinter par des Threads
    Par piokml dans le forum Général Python
    Réponses: 3
    Dernier message: 18/10/2012, 11h00
  2. Gtkmm comment automatiser le rafraichissement des widgets?
    Par Krishna dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 19/07/2009, 14h51
  3. [gtkmm] pointer sur des widgets
    Par MDiabolo dans le forum GTK+ avec C & C++
    Réponses: 0
    Dernier message: 20/03/2008, 12h44
  4. Réponses: 7
    Dernier message: 23/10/2005, 21h52
  5. Désactiver la protection des fichiers systéme
    Par cartonis dans le forum Sécurité
    Réponses: 6
    Dernier message: 13/08/2005, 19h17

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