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 :

PYQT, tableWidget et sqlite3


Sujet :

PyQt Python

  1. #21
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il me semble que ta table "TEST" a un défaut de construction: mon programme de lecture de cette table donne:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE "TEST" (
        "Date" TEXT
        "Valeur" TEXT,
        "Libellé" REAL,
        "Débit" REAL,
        "Crédit" REAL,
        "Solde" TEXT,
        "Paiement" TEXT,
        FOREIGN KEY("Paiement") REFERENCES "TYPE_PAIEMENT"("Paiement"));

    Et il manque une virgule à la ligne Date, ce qui trompe PyQt5 dans le numéro de colonne de la relation.

    Par ailleurs, la colonne "Paiement" de cette table "TEST" ne porte aucune valeur! Il faudrait l'initialiser avec une des valeurs de la colonne "Paiement" de la table "TYPE_PAIEMENT".

    Une fois ces 2 modifs faites, ça devrait marcher.

  2. #22
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2019
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Décembre 2019
    Messages : 62
    Points : 36
    Points
    36
    Par défaut combobox tableview sqlite
    Encore merci à tyrtamos pour son aide.
    Avec la création d'une clé, l'affichage dans le tableview se fait que si j'ai remplit le champs de la table avec une valeur de la clé. Est-ce normal et peut-on le contourner car je souhaite renseigner la table à posteriori ?
    Une idée serait de mettre une valeur par défaut dans ma table générale qui corresponde à une valeur de la clé mais ça fait un traitement en plus.

    Merci

  3. #23
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il s'agit plus d'un problème SQL. Pour sqlite3:
    - voir la syntaxe dans sa doc ici: https://www.sqlite.org/lang.html.
    - il y a aussi beaucoup d'autres informations sur Sqlite3: https://www.sqlite.org/docs.html

    Effectivement, je n'ai pas trouvé d'autre solution que de créer une valeur 'CHOISIR' (par exemple) dans la table de référence, et de mettre cette valeur par défaut à l'insertion d'une nouvelle ligne dans la table TEST.

    Voilà l'essai que j'ai fait:

    Structure SQL:

    Code SQL : 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
    CREATE TABLE "TYPE_PAIEMENT" (
    	"Paiement" TEXT NOT NULL UNIQUE,
     	PRIMARY KEY("Paiement")
        );
    INSERT INTO "TYPE_PAIEMENT" VALUES('CHOISIR');
    INSERT INTO "TYPE_PAIEMENT" VALUES('A');
    INSERT INTO "TYPE_PAIEMENT" VALUES('B');
    INSERT INTO "TYPE_PAIEMENT" VALUES('C');
    INSERT INTO "TYPE_PAIEMENT" VALUES('D');
    INSERT INTO "TYPE_PAIEMENT" VALUES('E');
    CREATE TABLE "TEST" (
    	"Date"	TEXT,
    	"Valeur"	TEXT,
    	"Libellé"	REAL,
    	"Débit"	REAL,
    	"Crédit"	REAL,
    	"Solde"	TEXT,
    	"Paiement" TEXT NOT NULL DEFAULT ('CHOISIR'),
    	FOREIGN KEY("Paiement") REFERENCES "TYPE_PAIEMENT"("Paiement")
    	);
    INSERT INTO "TEST" ("Date","Valeur","Libellé","Débit","Crédit","Solde") VALUES ('03/08/20','x',0,0,0,'X');
    INSERT INTO "TEST" ("Date","Valeur","Libellé","Débit","Crédit","Solde") VALUES ('04/08/20','y',0,0,0,'Y');
    INSERT INTO "TEST" ("Date","Valeur","Libellé","Débit","Crédit","Solde") VALUES ('05/08/20','z',0,0,0,'Z');

    la base de données est construite avec le code dont je t'ai donné le texte plus haut.

    A la 1ère exécution, la table "TEST" affiche la colonne "Paiement" avec la valeur par défaut "CHOISIR". Au double-clic, il est bien proposé l'une des valeurs de la table "TYPE_PAIEMENT".

    Au lieu de 'CHOISIR', on peut avoir n'importe quoi, y compris une chaine vide. Mais il vaut mieux inciter l'utilisateur à remplir les champs de cette colonne

    Dans les traitement ultérieurs, rien n'empêche de mettre une condition dans les requêtes sur la présence d'une "vraie" valeur de cette colonne.

  4. #24
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2019
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Décembre 2019
    Messages : 62
    Points : 36
    Points
    36
    Par défaut liste sqlite tableview
    ok merci j'imagine que pour mon projet j'aurais dû faire un dictionnaire à la place de passer en sql mais je vais continuer ainsi,
    encore merci

  5. #25
    Rédacteur/Modérateur
    Avatar de loufab
    Homme Profil pro
    Entrepreneur en solutions informatiques viables et fonctionnelles.
    Inscrit en
    Avril 2005
    Messages
    12 023
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Entrepreneur en solutions informatiques viables et fonctionnelles.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 12 023
    Points : 24 567
    Points
    24 567
    Par défaut
    Bonjour Salpat et Tyrtamos,

    Pour avoir une valeur dans un SELECT sans être obligé de le créer dans la table on utilise un UNION.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        ...
        sql = "SELECT ' CHOISIR' as dummy FROM maTable UNION "
        sq l= sql + " SELECT col1 FROM matable ORDER BY col1;"
     
        cur = self.db.cursor()
        cur.execute(sql)
        result = cur.fetchall()
        ...
    Le tri se fait sur l'ensemble de l'union et non pas sur le SELECT qui l'utilise donc pour l'avoir toujours au début l'astuce consiste à débuter par un espace.

    ça donne ceci :
    getRecordsSql >> SELECT ' CHOISIR' as col1 FROM Categorie UNION SELECT nom FROM categorie ORDER BY nom;
    (' CHOISIR',)
    ('Assurance',)
    ('Salaire',)
    ('Voiture',)
    ...

    Cordialement,

  6. #26
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2019
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Décembre 2019
    Messages : 62
    Points : 36
    Points
    36
    Par défaut
    bonjour,
    je ne sais pas si je dois continuer la discussion ou en ouvrir une autre ?
    J'ai voulu mettre en checkbox et un combobox dans la table sqlite mais il semble que la compatibilité des delegates pose problème, si je prends le premier le checkbox s'affiche mais pas le combo et inversement avec l'autre délégate ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # enregistre les contraintes de clés étrangères (plusieurs possible)
            for col, tab, champ1, champ2 in self.relations:
                self.model.setRelation(col, QtSql.QSqlRelation(tab, champ1, champ2))
                # force le chargement complet de la table contenant la clé étrangère
                modelref = self.model.relationModel(col)
                while modelref.canFetchMore( ):
                    modelref.fetchMore( )
    
    
            # met un delegate personnalisé pour l'édition version checkbox
            self.vuetable.setItemDelegate(QSqlRelationalDelegate(self.vuetable))
    
            # met un delegate personnalisé pour l'édition version combobox
            self.vuetable.setItemDelegate(QSqlRelationalDelegate(self.vuetable))
    En vous remerciant,

  7. #27
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Bonjour

    Citation Envoyé par salpat Voir le message
    je ne sais pas si je dois continuer la discussion ou en ouvrir une autre ?
    Ce serait mieux, car cela faciliterait l'aide aux personnes suivantes qui ont le même problème.


    Pour le reste, le delegate ne fonctionne pas comme ça. Il faut créer un (et un seul) delegate perso (une classe héritant du delegate standard), et lui dire dans ses différents modules qu'on veut un QCheckBox dans la colonne d'indice 3 (par exemple). et on laisse les autres colonnes être traitées par le delegate standard en lui repassant la main.

    Je n'ai pas le temps d'en dire plus aujourd'hui. Si je peux demain, je te fais un petit exemple.

  8. #28
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà quelques éléments concernant la programmation d'un delegate pour afficher et gérer un QCheckBox.

    Il faut d'abord résoudre un problème: si on se contente de demander l'affichage d'un QCheckBox dans les cases d'une colonne d'un QTableView, on obtient une case centrée à gauche, et ce n'est pas forcément beau. Le plus simple est alors d'empaqueter le QCheckBox dans un conteneur, par exemple un QFrame, ce qui permettra d'avoir le QCheckBox systématiquement au milieu de la case:

    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
    class MonCheckBox(QtWidgets.QFrame):
        """QCheckBox placé dans un QFrame
        """
     
        def __init__(self, parent=None):
            super().__init__(parent)
     
            # met un fond de couleur (optionnel!)
            self.setStyleSheet("background-color: yellow;")
     
            # crée le QChecBox à l'intérieur du QFrame
            self.box = QtWidgets.QCheckBox(self)
     
            # positionne le QCheckBox au milieu du QFrame
            posit = QtWidgets.QGridLayout()
            posit.addWidget(self.box, 0, 0)
            posit.setAlignment(QtCore.Qt.AlignCenter)
            posit.setContentsMargins(0, 0, 0, 0)
            self.setLayout(posit)
    A noter que la couleur jaune ici signalera en plus qu'on est en mode édition.

    Ensuite, on crée le delegate "perso". J'ai imaginé ici que la colonne des booléens est la 3ème colonne (indice 2), et qu'elle contient des entiers '0' et '1' (le type booléen n'existe pas dans sqlite3):

    Voici le code (largement commenté):

    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
    class MonSqlRelationalDelegate(QtSql.QSqlRelationalDelegate):
     
        #========================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
        #========================================================================
        def createEditor(self, parent, option, index):
            """Créer et initialise le widget d'édition
               aParent: type 'PyQt5.QtWidgets.QWidget'
               option: type 'PyQt5.QtWidgets.QStyleOptionViewItem'
               index: type 'PyQt5.QtCore.QModelIndex'
               Retourne l'éditeur utilisé
            """
            if index.column() == 2:
                # on est dans la colonne des booléens
     
                # crée le QCheckBox personnalisé
                editor = MonCheckBox(parent)
     
                # définit sa taille = taille de la case 
                editor.resize(option.rect.size())           
     
                # retourne le QCheckBox personnalisé
                return editor        
     
            else:
                # cas d'une autre colonne: on repasse la main à l'ancêtre
                return super().createEditor(parent, option, index)
     
        #========================================================================
        def setEditorData(self, editor, index):
            """Définit l'état du QCheckBox à l'entrée du mode édition
                 editor: QtWidgets.QWidget
                 index: QtCore.QModelIndex
               Retour: None
            """
     
            if index.column() == 2:
                # on est dans la colonne des booléens
     
                # récupère la valeur en booléen de la base de données, destinée à la case
                data = bool(index.model().data(index, QtCore.Qt.EditRole))
     
                # définit l'état coché ou non du QCheckBox
                editor.box.setChecked(data)
     
            else:
                # cas d'une autre colonne: on repasse la main à l'ancêtre
                super().setEditorData(editor, index)
     
        #========================================================================
        def setModelData(self, editor, model, index):
            """ Enregistre la valeur modifiée dans la base de données 
                  editor: type 'QtWidgets.QWidget'
                  model: type 'QtCore.QAbstractItemModel'
                  index: type 'QtCore.QModelIndex'
                Retour: None
            """
     
            if index.column() == 2:
                # on est dans la colonne des booléens
     
                # lit l'état (booléen) de la coche de la case à cocher
                coche = editor.box.isChecked()
     
                # enregistre dans le modèle la valeur affichée du QLineEdit
                model.setData(index, int(coche), QtCore.Qt.EditRole)
     
                return
     
            else:
                # cas d'une autre colonne: on repasse la main à l'ancêtre
                super().setModelData(editor, model, index)
     
                return
     
        #========================================================================
        def paint (self, painter, option, index):
            """permet d'afficher un QCheckBox dans les colonnes booléennes
               en dehors du mode "édition" de la cellule 
            """
     
            if index.column() == 2:
                # on est dans la colonne des booléens
     
                # lit la donnée de la base, et convertit en booléen (0=False, 1=True)
                data = bool(index.model().data(index, QtCore.Qt.EditRole))
     
                # dessine un QCheckBos avec la bonne coche
                self.drawCheck(painter, option, option.rect, QtCore.Qt.Checked if data else QtCore.Qt.Unchecked)
     
            else:
                # cas d'une autre colonne: on repasse la main à l'ancêtre
                super().paint(painter, option, index)
    La méthode "paint" ne sert qu'à afficher un QCheckBox alors qu'on N'est PAS en mode édition. A défaut, les cases afficheraient les 0 et 1 de la base de données, et ne passeraient en QCheckBox que pendant l'édition (double-clic).

    On voit bien comment on traite le fait que la colonne d'indice 2 doit avoir notre QCheckBox personnalisé. On pourrait aussi avoir d'autres types de widgets dans d'autres colonnes (elif ... elif ...). Par exemple un QDoubleSpinBox pour les flottants (qui sont les "double" du C) ou un QComboBox, ou pourquoi pas un widget spécial (à construire) pour afficher et mettre à jour des dates, etc... Et le dernier "else" repasse la main à l'ancêtre (le delegate normal) pour traiter les autres colonnes normales.

  9. #29
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2019
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Décembre 2019
    Messages : 62
    Points : 36
    Points
    36
    Par défaut sélection dans tableview
    bonsoir,
    j'ai mis mes données dans un tableView avec qtdesigner et je n'arrive plus à récupérer les informations du tableau, ligne,column et données.

    L’erreur vient-elle de QAbstractItemView ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.AllEditTriggers)
            self.tableView.setDragEnabled(True)
            self.tableView.setAlternatingRowColors(True)
            self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
    Bonne soirée et encore merci pour la pédagogie

  10. #30
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Désolé pour mon absence de réponse, mais je ne comprends pas ce que tu cherches à faire, et je ne connais pas ce code.

    Si le pb se pose encore: donne plus d'infos.

  11. #31
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2019
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Décembre 2019
    Messages : 62
    Points : 36
    Points
    36
    Par défaut SQLITE PYQT5
    Bonjour tyrtamos ,
    encore merci j'ai réussi en insistant.
    si tu peux m'orienter sur ma nouvelle discussion https://www.developpez.net/forums/d2...lite-combobox/.
    je souhaite pouvoir faire une recherche fulltext par colonne, je n'ai pas réussi par entête de tableau mais j'y arrive avec un qlineedit, je voudrait juste récupérer le nom d'entête colonne et l'index de colonne avec un combobox.
    Merci

  12. #32
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2019
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Décembre 2019
    Messages : 62
    Points : 36
    Points
    36
    Par défaut Sélection multiple ligne
    Bonjour,
    merci pour la réponse
    je souhaite faire des modifications en sélectionnant plusieurs ligne dans mon tableview
    j'imagine qu'il faut passer par firstRowChanged () mais je n'arrive pas à l'appliquer.
    En vous remerciant,

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/12/2012, 21h19
  2. [PyQt] [py2exe]
    Par Zorro dans le forum Py2exe
    Réponses: 2
    Dernier message: 05/05/2006, 13h36
  3. Réponses: 1
    Dernier message: 28/11/2005, 23h20
  4. [PyQt] Qt Designer et Qpixmap
    Par parp1 dans le forum PyQt
    Réponses: 2
    Dernier message: 17/06/2005, 12h04
  5. [PyQt] QImage
    Par Jbx 2.0b dans le forum PyQt
    Réponses: 1
    Dernier message: 01/02/2005, 23h06

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