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 :

QSqlQueryModel, Oracle, ODBC et tout le toutim [QtSql]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Par défaut QSqlQueryModel, Oracle, ODBC et tout le toutim
    Bonjour à tous,

    Je débute avec PyQt et je suis également nouveau sur le forum.

    J'ai un problème pour afficher le résultat d'un select dans un QTableView
    L'exemple que j'utilise ici est tiré de la doc
    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
     
    # Requête SQL ultra-simple 
    SQL = "select nprospect,cnom from prospect where nprospect=6631"
     
     
    import sys
    def connection():
        db = QtSql.QSqlDatabase.addDatabase('QODBC')
        connstr = "Driver={Microsoft ODBC for Oracle};CONNECTSTRING=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=...)(PORT=1521)))(CONNECT_DATA=(SID=dbtest)));Uid=....;Pwd=p....cvqtest;"
        db.setDatabaseName(connstr)
        if not db.open():
            QtGui.QMessageBox.critical(None, u'Ne peut ouvrir la database',
                    u"J'ai rencontré un problème en essayant de me connecter à la base de données\n %s" % db.lastError().text(),
                    QtGui.QMessageBox.Cancel)
            return False
        print db.tables()  # La connection est valide ! Preuve par la liste des tables
        return True
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        if connection():
            model = QtSql.QSqlQueryModel()
            model.setQuery(SQL)
            view = QtGui.QTableView()
            view.setModel(model)
            view.setWindowTitle('Tester QtSql.QSqlQueryModel()')
            view.show()
    Je précise deux choses :
    1. La requête est correcte
    2. Ma connexion fonctionne car j'obtiens la liste des tables


    Pourtant la fenêtre ne me montre rien du tout et semble partir en boucle.

    Quelqu'un a-t-il déjà rencontré ce problème ?

    Merci d'avance pour vos réponses

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Juste une idée.

    Ce qui m'étonne, c'est que tu ouvres ta base de donnée avec connection(), mais que tu n'utilises pas la connexion ouverte 'db'.

    A mon avis:

    - la fonction connection() devrait renvoyer db (ou None en cas d'échec).

    - il faudrait donc commencer avec "db=connection()".

    - le test de réussite deviendrait donc: "if db!=None:"

    - il faudrait ajouter db au setQuery: model.setQuery(SQL, db)

    (Et il faudrait fermer proprement la base après usage)

    Tyrtamos

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Par défaut


    Bonjour et merci beaucoup pour la rapidité de ta réponse

    En effet, ainsi, cela marche déjà beaucoup mieux.

    Il me reste un petit problème à résoudre sur lequel je vais bosser dès que
    j'en aurais le temps :

    Le widget ne part plus en vrille mais n'affiche rien dans les colonnes ! Note qu'il affiche autant de ligne que ce que la requête retourne. Je planche encore dessus et je posterai la solution afin que d'autre puissent en bénéficier.

    A part cela, Qt c'est vraiment top.
    Je développe actuellement une application pour mon boulot qui doit tourner sous au moins windows et linux. Jusqu'ici, j'utilisais Powerbuilder. C'est lourd et a peu près limité à winchose. Mais depuis deux ans, j'ai découvert Python que j'utilise de plus en plus pour les programmes sans interface et c'est génial. Pour en revenir a Qt vs Powerbuilder, lorsque, avec ce dernier, je veux que mes widgets se redimensionnent avec la fenêtre, je suis obligé d'intercepter les évènements de redimensionnement de ma fenêtre pour les répercuter sur mes widget. Avec Qt, tout cela est automatique ou presque, il suffit de bien choisir ses layouts et ses sizePolicy.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà ton code tel que je l'organiserais:

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Python 2.7
     
    import sys
    import sqlite3
     
    from PyQt4 import QtCore, QtGui, QtSql
     
    #############################################################################
    def ouvrebase(basesql):
        """ouvre la base 'basesql' et renvoie la connexion (None si échec)"""
        db = QtSql.QSqlDatabase.addDatabase(u"QSQLITE")
        db.setDatabaseName(basesql)
        if not db.open():
            db = None
        return db
     
    #############################################################################
    def fermebase(db):
        if db!=None:
            db.close()
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
        def __init__(self):
            QtGui.QWidget.__init__(self, None)
            self.setWindowTitle('Test QtSql et QTableView')
            self.resize(500, 250)
     
            # ouverture de la base SQL
            basesql = "basetest.db3"
            self.db = ouvrebase(basesql)
            if self.db == None:
                self.close()
     
            # création du tableau et de sa liaison avec la base SQL
            model = QtSql.QSqlQueryModel()
            self.view = QtGui.QTableView(self)
            self.view.setModel(model)
     
            # positionnement du QTableView dans la fenêtre
            posit = QtGui.QGridLayout()
            posit.addWidget(self.view, 0, 0)
            self.setLayout(posit)        
     
            # exécution de la requête
            requete = "select photo,titre from photos where section='C'"
            model.setQuery(requete, self.db)
            self.view.resizeColumnsToContents()
     
        def closeEvent(self, event=None):
            """Méthode appelée automatiquement à la fermeture de la fenêtre"""
            #fermeture de la base
            fermebase(self.db)
            event.accept()
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Commentaires:

    - il est intéressant de créer pour la fenêtre une classe qui dérive de QWidget ou de QMainWindow (fenêtre avec menu), parce que ça permet d'utiliser des méthodes existantes en les surchargeant (ici, closeEvent).

    - il est intéressant de placer en dehors, les instructions d'ouverture et de fermeture de la base SQL, parce que ça permet de changer plus facilement de type de base (ici sqlite3).

    Il faut, bien entendu adapter les données à ton pb.

    En ce qui me concerne, je préfère utiliser un modèle QSqlRelationalTableModel, qui me permet d'exécuter des requêtes multi-tables complexes sur des bases de données relationnelles ayant des contraintes d'intégrité référentielles.

    Qt4 est une bibliothèque graphique très puissante. Il ne faut pas oublier que c'est elle qui est utilisée pour le bureau graphique KDE des Linux (comme Gtk pour Gnome). De plus, QtDesigner permet de créer des fenêtres complexes qui seraient très pénibles à faire 'à la main'.

    Tyrtamos

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/11/2006, 12h22
  2. Réponses: 6
    Dernier message: 01/08/2006, 18h12
  3. [VB6] Oracle ODBC Driver et sessions inactive dans oracle
    Par sboffin dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 17/05/2006, 21h46
  4. Dtriver oracle ODBC
    Par exempleinfo dans le forum Oracle
    Réponses: 1
    Dernier message: 07/03/2006, 02h38
  5. Oracle ODBC driver connect
    Par yoann dans le forum Access
    Réponses: 1
    Dernier message: 15/11/2005, 17h57

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