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

PyQt Python Discussion :

Afficher une recherche avancée dans un QTablewidget


Sujet :

PyQt Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2020
    Messages : 25
    Points : 15
    Points
    15
    Par défaut Afficher une recherche avancée dans un QTablewidget
    Salut à tous.
    je code un logiciel d'enregistrement et recherche et tri de contacts dans une base de données SQLite3 en python 3.9
    Mes contacts sont stockés dans une table sqlite3 nommée Annuaire.
    je dispose d'un widget sur lequel j'ai:
    1. Un QTableWidget permettant d'afficher les résultats des requetes
    2. D'un QComboBox nommé cborecherche qui contient les étiquettes des colonnes de ma table Annuaire
    3. D'un QLineEdit nommé Textboxrecherche qui me permettra de faire le tri
    Mon objectif est de faire le tri lettre par lettre et afficher le résultat dans le QTablewidget.
    Par exemple: je choisis une valeur de la QComboBox par exemple Noms et ensuite si j'entre la lettre "b" dans la textbox cela doit me trier et afficher tous les noms commencant par la lettre "b". Si de plus j'ajoute la lettre "e" cela me tri et m'affiche tous les noms commencant par "be" et ainsi de suite. (Donc un tri lettre par lettre)
    L'affichage dans le QTableWidget marche bien mais le problème c'est la syntaxe sqlite3 qui doit me permettre de faire ce genre de tri avancé.
    J'ai déja regardé au net fatigué et je suis tombé sur la fonction Like qui fait pas mal de chose mais ne me fait pas ce genre de tri.
    Voici mon code simplifié
    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
     
            self.textboxrecherche.textChanged.connect(self.research)
     
        def research(self):
            #self.table.clear()
            data = [self.cborecherche.currentText(), self.textboxrecherche.text()]
            database_creation()
            connexion = sqlite3.connect("phonebook_Database.db")
            cur = connexion.cursor()
            req = "SELECT* FROM Annuaire WHERE ? LIKE ? "
            cur.execute(req, data)
     
            # Affichage des éléments triés de la table dans mon QtableWidget nommé table
            myResult = cur.fetchall()
            self.table.setRowCount(0)
            for i, row_data in enumerate(myResult):
                self.table.insertRow(i)
                for j, data in enumerate(row_data):
                    self.table.setItem(i, j, QtWidgets.QTableWidgetItem(str(data)))
    Merci pour votre aide.
    C'est vrai que le pb concerne beaucoup plus sqlite mais j'ai pas trouvé un forum sqlite3 de pyhon sur le site.
    mes excuses pour la longueur de mon problème.

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 484
    Points : 9 286
    Points
    9 286
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je ferais différemment ce genre de chose.

    Quand je fais une extraction d'une base de données relationnelle sqlite3, je crée une table temporaire avec le pilote de Python (qui possède un plus grand potentiel d'adaptation que celui de PyQt5), et j'affiche cette table avec un QTableView et son modèle relationnel QSqlRelationalTableModel. Pour les tris d'une même table, il suffit de cliquer sur la bonne colonne pour avoir les mêmes données triées selon la colonne dans un sens ou dans l'autre.
    Dans des cas complexes, on peut ajouter un QSortFilterProxyModel, qui s'interpose entre le modèle normal et le QTableView.

    Un QLineEdit peut émettre un signal à chaque modification de caractère, qui peut déclencher le filtrage=> table temporaire => affichage (sqlite3 et PyQt5 sont très rapides (écrits en C / C++)).

  3. #3
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2020
    Messages : 25
    Points : 15
    Points
    15
    Par défaut Reponse
    Merci pour votre réponse mais honnêtement j'avais tenté le qtableview et les délégués mais c'était très complexe à comprendre pour moi. Les termes comme rôle, index et autre difficile à comprendre en pratique.
    Pourtant j'ai l'impression que c'est très riche mais malheureusement j'avais abandonné les qtableview pour me tourner vers le qtablewidget facile à comprendre

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 484
    Points : 9 286
    Points
    9 286
    Billets dans le blog
    6
    Par défaut
    Alors, avec un QTableWidget, voilà quelques principes pour votre pb:

    - puisque le QTableWidget ne sera pas en relation automatique avec la base, vous n'avez pas besoin du pilote sqlite3 de PyQt5: seul le pilote de Python sera utile.

    - il faut préparer la fonction qui permettra de remplir le QTableWidget avec la "liste de liste" venant du SELECT de SQL.

    - A chaque nouveau caractère tapé dans le QLineEdit, celui-ce devra émettre un signal qui déclenchera les opérations suivantes:
    ---- lecture du QLineEdit
    ---- lecture du QCombobox pour voir de quelle colonne on parle
    ---- construction et envoie de la requête SQL pour faire la sélection demandée
    ---- réception du résultat sous forme d'une "liste de liste"
    ---- effacement d'un éventuel contenu du QTableWidget
    ---- écriture de la liste de liste dans le QTableWidget

    Pour la requête SQL, il faut utiliser WHERE pour préciser la condition permettant de retenir une ligne dans la sélection: toutes les données de la colonne dont les 1ers caractères sont égaux aux caractères du QLineEdit.
    Il faudra aussi choisir si la sélection doit ou non tenir compte de la casse (majuscule/minuscule), et même si elle doit neutraliser ou non les caractères accentués.

    Au fait, ce qui est demandé n'est pas un tri mais une sélection ou un filtrage: la liste obtenue sera en général plus petite que la liste complète.

    Pour la construction des requêtes SQL, il y a une bonne doc chez sqlite3: https://www.sqlite.org/lang.html.
    Celle de SELECT est ici: https://www.sqlite.org/lang_select.html
    Voir aussi une partie utile pour ce problème, et en particulier pour la manipulation des chaînes de caractères: https://www.sqlite.org/lang_corefunc.html

    Il est possible qu'on puisse utiliser un QCompleter avec le QLineEdit, mais je n'ai pas creusé cette solution.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2020
    Messages : 25
    Points : 15
    Points
    15
    Par défaut
    merci pour ta reponse tyrtamos
    Je reposte encore mon code simplifié
    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
     
            self.textboxrecherche.textChanged.connect(self.research)
     
     
        def research(self):
            #self.table.clear()
            data = [self.cborecherche.currentText(), self.textboxrecherche.text()]
            connexion = sqlite3.connect("phonebook_Database.db")
            cur = connexion.cursor()
            req = "SELECT* FROM Annuaire WHERE ? LIKE ? "
            cur.execute(req, data)
     
            # Affichage des éléments filtrés de la table dans mon QtableWidget nommé table
            myResult = cur.fetchall()
            self.table.setRowCount(0)
            for i, row_data in enumerate(myResult):
                self.table.insertRow(i)
                for j, data in enumerate(row_data):
                    self.table.setItem(i, j, QtWidgets.QTableWidgetItem(str(data)))
    Dans ce code j'ai déja résolu plusieurs points que tu poses dans ta réponse.
    mon QLineEdit nommé textboxrecherche est déjà lié au signal textChanged
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     self.textboxrecherche.textChanged.connect(self.research)
    Et pour la récupération du résultat obtenu afin de l'afficher dans le QTablewidget tout est ok comme ci dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     # Affichage des éléments filtrés de la table dans mon QtableWidget nommé table
            myResult = cur.fetchall()
            self.table.setRowCount(0)
            for i, row_data in enumerate(myResult):
                self.table.insertRow(i)
                for j, data in enumerate(row_data):
                    self.table.setItem(i, j, QtWidgets.QTableWidgetItem(str(data)))
    Mon probleme principal est au niveau de la syntaxe sql qui me permettra de faire ce genre de filtrage lettre par lettre.
    Pour la casse la fonction LIKE résoud déjà ce probleme et j'ai aussi éssayé avec le mot clé WHERE mais sans succès.
    J'ai également jeté un coup d'oeil sur les liens que tu as proposé meme comme c'est trop de shéma que je ne comprends pas trop.
    Et pour la lecture des valeurs entrées dans la QComboBox nommé cborecherche et la QLineEdit c'est dans ce bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     data = [self.cborecherche.currentText(), self.textboxrecherche.text()]
            connexion = sqlite3.connect("phonebook_Database.db")
            cur = connexion.cursor()
            req = "SELECT* FROM Annuaire WHERE ? LIKE ? "

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 484
    Points : 9 286
    Points
    9 286
    Billets dans le blog
    6
    Par défaut
    Voilà un petit exemple d'une requête SQL:

    j'ai une petite base de données qui contient une table qui s'appelle "matable":

    names adresses ages
    Alice Adresse Alice 12
    Bob Adresse Bob 25
    Carol Adresse Carol 29
    Bobin Adresse Donald 32
    Emma Adresse Emma 41
    Je cherche toutes les lignes dont le nom (colonne "names") commencent pas "Bo":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        cur.execute('SELECT names, adresses, ages FROM matable WHERE substr(names,1,2)="Bo"')
    Un "records = cur.fetchall()" donne:

    [('Bob', 'Adresse Bob', 25), ('Bobin', 'Adresse Donald', 32)]
    Qui est la liste de listes (ou plutôt une liste de tuples) attendue.

    Après, la requête doit être paramétrée avec:
    - le nom de la colonne voulue
    - la longueur du mot du QLineEdit
    - le mot du QLineEdit
    Ce qui n'est qu'une manipulation de chaines de caractères en Python.

    Voilà ce que ça donnerait avec mon exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        col = "names"
        mot = "Bo"
        lgmot = len(mot)
        requete = 'SELECT names, adresses, ages FROM matable WHERE substr({},1,{})="{}"'.format(col, lgmot, mot)    
        cur.execute(requete)    
        records = cur.fetchall()
    Ce qui donne, bien sûr, le résultat attendu.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2020
    Messages : 25
    Points : 15
    Points
    15
    Par défaut Reponse
    Merci infiniment tyrtamos. Je vais essayer avec ça

Discussions similaires

  1. Réponses: 7
    Dernier message: 18/04/2014, 14h58
  2. [MySQL] Afficher le resultat d'une recherche multicritére dans une autre page
    Par nash40 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 23/01/2013, 13h45
  3. Afficher une recherche faite dans l'active directory
    Par clemantine dans le forum ASP.NET
    Réponses: 4
    Dernier message: 18/06/2012, 20h12
  4. recherche avancée dans une combobox
    Par Chico_Latino dans le forum C#
    Réponses: 1
    Dernier message: 07/05/2010, 12h08
  5. [RegEx] Recherche avancée dans une base
    Par renator67 dans le forum Langage
    Réponses: 14
    Dernier message: 24/01/2007, 00h23

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