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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys, os
from PyQt5 import (QtWidgets, QtCore, QtSql)
#############################################################################
def ouvrebaseqt(basesql):
"""ouvre la base 'basesql' et renvoie la connexion (None si échec)
"""
if not os.path.exists(basesql):
db = None
else:
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(basesql)
if not db.open():
db = None
return db
#############################################################################
def fermebaseqt(db):
if db!=None:
db.close()
#############################################################################
class VoirTableSql(QtWidgets.QMainWindow):
def __init__(self, basesql, nomtable, parent=None):
super().__init__(parent)
self.setWindowTitle("Affichage de la table %s" % (nomtable,))
self.resize(800, 600)
# ouverture de la base SQL
self.basesql = basesql
self.db = ouvrebaseqt(self.basesql)
if self.db==None:
sys.exit() # échec d'ouverture base => fermeture de la fenêtre
# table à afficher
self.nomtable = nomtable
# création du modèle et de sa liaison avec la base SQL
self.model = QtSql.QSqlRelationalTableModel(self, self.db)
# stratégie en cas de modification de données par l'utilisateur
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.bouton = QtWidgets.QPushButton("Afficher la fenêtre secondaire!")
self.bouton.clicked.connect(self.creamapper)
# création de la table et de son lien avec le modèle
self.vuetable = QtWidgets.QTableView(self)
self.vuetable.setModel(self.model)
self.vuetable.setItemDelegate(QtSql.QSqlRelationalDelegate(self.vuetable))
# pour activer le tri en cliquant sur les têtes de colonnes
self.vuetable.setSortingEnabled(True)
# positionnement du QTableView et du QPushButton dans la fenêtre
self.setCentralWidget(QtWidgets.QFrame())
posit = QtWidgets.QGridLayout()
posit.addWidget(self.vuetable, 0, 0)
posit.addWidget(self.bouton, 1, 0)
self.centralWidget().setLayout(posit)
# affiche la table demandée
self.model.setTable(self.nomtable)
self.model.select() # peuple le modèle avec les données de la table
# tri si nécessaire au lancement selon la colonne 0
self.model.sort(0, QtCore.Qt.AscendingOrder) # ou DescendingOrder
# ajuste la largeur des colonnes en fonction de leurs contenus
self.vuetable.resizeColumnsToContents()
#========================================================================
def creamapper(self):
"""création de la fenêtre secondaire avec le QDataWidgetMapper
"""
self.voirmapper = VoirMapper(self.model)
# chaque changement de ligne demandera la mise à jour du mapper
self.vuetable.selectionModel().currentRowChanged.connect(self.voirmapper.affiche)
# pour remplir les QLineEdit au lancement par la 1ère ligne du QTableView
self.vuetable.setCurrentIndex(self.vuetable.model().index(1,0))
self.vuetable.setCurrentIndex(self.vuetable.model().index(0,0))
# affichage de la fenêtre
self.voirmapper.show()
#========================================================================
def closeEvent(self, event=None):
"""Méthode appelée automatiquement à la fermeture de la fenêtre
utile ici pour fermer la base si elle est encore ouverte
"""
fermebaseqt(self.db)
event.accept()
#############################################################################
class VoirMapper(QtWidgets.QWidget):
#========================================================================
def __init__(self, model, parent=None):
super().__init__(parent)
self.resize(300, 200)
self.model = model
self.edit1 = QtWidgets.QLineEdit(self)
self.edit2 = QtWidgets.QLineEdit(self)
posit = QtWidgets.QGridLayout()
posit.addWidget(self.edit1, 0, 0)
posit.addWidget(self.edit2, 1, 0)
self.setLayout(posit)
self.mapper = QtWidgets.QDataWidgetMapper(self)
self.mapper.setModel(self.model)
self.mapper.addMapping(self.edit1, 0) # 0: 1ère champ de la base
self.mapper.addMapping(self.edit2, 1) # 1: 2ème champ de la base
#========================================================================
def affiche(self, qindex, qindexprec=None):
"""met à jour l'affichage du mapper avec le QModelIndex transmis
"""
self.mapper.setCurrentModelIndex(qindex)
#############################################################################
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
basesql = "mabase.db3"
nomtable = "matable"
fen = VoirTableSql(basesql, nomtable)
fen.show()
sys.exit(app.exec_()) |
Partager