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

Multithreading Discussion :

Remplir un QTableWidget en parcourant une base de données [QtConcurrent]


Sujet :

Multithreading

  1. #1
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2015
    Messages
    252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2015
    Messages : 252
    Points : 272
    Points
    272
    Par défaut Remplir un QTableWidget en parcourant une base de données
    Bonjour,

    je voudrais remplir un QtableWidget (et non une QTableView) en utilisant QConcurrent.
    J'arrive à mes fins mais j'ai dû ajouter dans mon main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        qRegisterMetaType<QVector<int> >("QVector<int>");
        qRegisterMetaType<QList<QPersistentModelIndex> >("QList<QPersistentModelIndex>");
        qRegisterMetaType<QItemSelection>("QItemSelection");
        qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>("QAbstractItemModel::LayoutChangeHint");
    sans trop comprendre quel est exactement le problème.

    Cependant, j'ai lu plusieurs fois que piloter des éléments graphiques de la fenêtre (QTableWidget en est un) à partir d'un code appelé par le thread était "malsain" ?
    Donc, existe-t-il une approche "recommandable" pour utiliser une requête SQL dans un thread secondaire ? Est-ce compatible avec le remplissage d'un QTableWidget de la manière suivante :
    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
              ui->table->setUpdatesEnabled( false ) ;
              ui->table->setRowCount(query.size());
     
              int index=0;
              while (query.next())
              {
                  ui->table->setItem(index,0,new QTableWidgetItem(query.value(0).toString()));
                  ui->table->setItem(index,1,new QTableWidgetItem(query.value(1).toString()));
                  ui->table->setItem(index,2,new QTableWidgetItem(query.value(2).toString() + " " + query.value(3).toString()));
                  ui->table->setItem(index,3,new QTableWidgetItem(query.value(4).toString()));
                  index++;
                   if (bfutureStop == true) return;
              }
     
     
            //Lancer le tri par défaut
              sortCol = 2;
              sortOrder = Qt::AscendingOrder;
              ui->table->sortByColumn(3, sortOrder);
              ui->table->sortByColumn(2, sortOrder);
     
           //Select First Row
              ui->table->selectRow(0);
              ui->table->setUpdatesEnabled( true ) ;
    Merci.

  2. #2
    Membre régulier
    Inscrit en
    Février 2004
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 84
    Points : 90
    Points
    90
    Par défaut
    Bonjour,

    Pourquoi tu ne passe pas par les signaux et slots qui sont sûrs entre thread. Dans ton thread qui lit la BDD tu mets un emit et tu récupère le message dans un slot du thread principal qui pilote l'interface graphique.

  3. #3
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2015
    Messages
    252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2015
    Messages : 252
    Points : 272
    Points
    272
    Par défaut
    Bonjour,

    Non, cette option ne fonctionne pas à ma connaissance et suivant mes tests.
    Des approches avec modification de Qt :: ConnectionType (Qt :: QueuedConnection ou Qt :: BlockingQueuedConnection ) restent limitées.

    Cdlt.

  4. #4
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 607
    Points : 188 574
    Points
    188 574
    Par défaut
    Citation Envoyé par ApproxDev Voir le message
    Cependant, j'ai lu plusieurs fois que piloter des éléments graphiques de la fenêtre (QTableWidget en est un) à partir d'un code appelé par le thread était "malsain" ?
    Le dessin s'effectue uniquement dans un fil d'exécution, tenter des modifications de l'extérieur donnera des messages d'erreur.

    Citation Envoyé par ApproxDev Voir le message
    Non, cette option ne fonctionne pas à ma connaissance et suivant mes tests.
    Et… ? C'est un peu court, jeune homme !, s'exclame un squelette. Qu'est-ce qui ne fonctionne pas ? Pour Qt, c'est vraiment l'approche à privilégier dans pas mal de cas. Quels tests as-tu effectués ? Quel en a été le résultat ?

    Citation Envoyé par ApproxDev Voir le message
    Cdlt.
    Moi aussi, j'aime écrire des choses imprononçables.
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  5. #5
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2015
    Messages
    252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2015
    Messages : 252
    Points : 272
    Points
    272
    Par défaut
    Bonjour,

    Cdlt : Cordialement. Une abréviation comme WE, comme Qt qui est plutôt un acronyme.

    Pour le reste, accéder à une base distante (par internet) et charger quelques enregistrements gèlent l'interface graphique... même avec des signaux et slots, surtout s'ils sont issus de cet interface graphique. J'en ai fait l'expérience et c'est clairement exprimé dans certaines mais rares discussions anglo-saxonnes. Il y a la théorie générale (le thread) et son utilisation appliquée à des cas particuliers (ici l'accès à une base de données distante et le parcours d'une table importante en nombre d'enregistrements à usage statistique avec le rafraîchissement régulier du GUI pendant toute la durée de l'opération). Sur un petit volume, ce gel est à peine perceptible. Mais telle n'est pas ma situation. Ceci dit le web est vaste et je ne prétends pas avoir parcouru toutes les solutions. Il y a peut-être moyen d'échapper à cette contrainte, de la contourner, d'autant que les évolutions de Qt sont significatives et fréquentes. Ce qui était impossible pour un auteur il y a 2 ans, est peut-être réalisable facilement actuellement. C'était la deuxième partie de ma question initiale.

    Pour la première partie,
    Citation Envoyé par ApproxDev Voir le message
    J'arrive à mes fins mais j'ai dû ajouter dans mon main.cpp[...]
    je demandais un petit peu d'éclaircissement sur la réclamation exprimée au débogage qui, une fois satisfaite, fonctionne correctement. Je suis incapable d'expliquer correctement le mécanisme qui conduit à l'expression de cette insuffisance (au niveau déclaration) précisée par le débogueur.

    Enfin pour ma réponse, celle-ci signifie simplement à mon interlocuteur que ce qu'il propose est une piste que j'ai explorée au début et que je qualifie de limitée dans le cadre de mon exploitation. D'un autre côté, ma réponse est aussi laconique (i.e. sans code) que la sienne, mais pas plus.

    Au final, je n'insiste pas. Je considère le problème comme résolu surtout si "d'une manière générale", il est facile de le traiter classiquement.

    Cordialement.

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 107
    Points : 189
    Points
    189
    Par défaut
    Bonsoir,
    d'autant que les évolutions de Qt sont significatives et fréquentes. Ce qui était impossible pour un auteur il y a 2 ans, est peut-être réalisable facilement actuellement.
    La partie sql à peu évoluée depuis Qt4 car elle est "mature".
    Voici un peu de lecture datant de 2007 mais qui reste d'actualité : http://www.linuxjournal.com/article/9602
    (4 pages)

    Au faite, mon bout de code sur le Drag and Drop entre QTableWidgets t'a servi ?

  7. #7
    Membre régulier
    Inscrit en
    Février 2004
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 84
    Points : 90
    Points
    90
    Par défaut
    Bonjour,

    Bon j'ai pris quelques minutes pour tester le concept. voici le projet qwidgetthreadtest.zip. Un thread se charge de lire les données toutes les 100 ms (dans cet exemple on ne lit rien mais ce n'est pas le problème). L'info est ensuite envoyée par un signal et reçu dans le slot slotMsg qui se charge d'ajouter une ligne dans le QTableWidget. Enfin la "mini calculatrice" permet de voir que le programme principal ne semble pas ralenti.
    Voila je ne sais pas si ça correspondant à ta demande ni si ça va te servir.

  8. #8
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2015
    Messages
    252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2015
    Messages : 252
    Points : 272
    Points
    272
    Par défaut
    Bonjour Jlbrd,

    Sympa... et merci pour le temps passé. Je branche ma base de données sur ton travail (enfin je vais créer une SQLite à la place de la base MySQL pour le retour de test) et te tiens au courant.
    Mais j'émets déjà un "signal" : tu lances ton thread à partir d'un bouton, fenêtre ouverte et dessinée donc. Ce ne sera pas mon cas. Je lance mon thread à l'ouverture de la fenêtre et cela change beaucoup de choses contrairement à ce qu'on pourrait croire. Donc, il faut que la fenêtre et tous ses composants se dessinent et que le lancement du thread soit automatique. A partir de "ce" moment (de ces moments) la progression du chargement de la table SQL et les divers messages s'il y a lieu sont affichés.

    La semaine est un peu chargée... mais j'essaie avant vendredi prochain. Cordialement.

  9. #9
    Membre régulier
    Inscrit en
    Février 2004
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 84
    Points : 90
    Points
    90
    Par défaut
    Salut voici une version un peu différente qwidgetthreadtestdb.zip dont le thread lit une base SQLite. Le programme commence par créer et alimenter la base si nécessaire puis lance le thread qui lit cette bdd et émet par signal les infos. Une ligne est insérée ou mise à jour dans le QTableWidget suivant si la ligne existe déjà ou pas. Deux diodes permettent de visualiser les ajouts et le mises à jour. Au début on a que des ajouts qui diminuent de plus en plus. Tout ça semble fonctionner correctement sans ralentir l'interface principale qui est pourtant bien plus mise à jour.

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

Discussions similaires

  1. [PDF] Remplir un formulaire PDF avec une base de données
    Par psgkiki dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 31/03/2009, 17h40
  2. remplir jList a partir d'une base de données
    Par Taoufik109 dans le forum Composants
    Réponses: 2
    Dernier message: 24/11/2008, 13h09
  3. Réponses: 1
    Dernier message: 03/08/2007, 04h15
  4. Réponses: 2
    Dernier message: 30/07/2007, 12h23
  5. Remplir jtable a partir d'une base de donnée mysql
    Par chris81 dans le forum Composants
    Réponses: 3
    Dernier message: 26/04/2007, 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