Lire et sauver des informations dans une base de données
Question
A l'aide de
phpMyAdmin
, créez la base de données nomméebddFormation
(si ce n'est pas déjà fait !) et la tableuser
conformément à la partie précédente "Accès à une base de données MySQL".Remplissez la table avec des valeurs de votre choix.
Concevez un programme nommé
appSgbd
ayant une IHM composée de 2 parties. La première permet d'afficher la liste des noms de la table user. En cliquant sur un nom, il est possible de mettre à jour le nom et login ou d'effacer cet utilisateur.La deuxième partie permet la création d'un nouvel utilisateur (vous pouvez vous inspirer de l'IHM ci-dessous).
Indice
Connexion à la base de données : Utilisation de la méthode statique de QSqlDatabase
en précisant le pilote à utiliser :
db = QSqlDatabase::addDatabase("QMYSQL");
Widget QListView
: Quand on clique sur une ligne de la QListView
, le signal clicked(QModelIndex)
est émis. Il faut capter ce signal et le raccorder à un slot
de la classe.
connect(ui->lvTable, SIGNAL(clicked(QModelIndex)), this, SLOT(onSelectLineList(QModelIndex)));
Ici, le signal clicked(QModelIndex)
du widget QListView
est connecté au slot onSelectLineList(QModelIndex)
créé dans la classe CIhmAppSgbd
.
Le paramètre émis avec le signal (QModelIndex
) désigne l'objet de gestion de la ligne sélectionnée.
void CIhmAppSgbd::onSelectLineList(QModelIndex mi)
{
QSqlQuery q(db);
q.prepare("SELECT * FROM user WHERE login=:login");
q.bindValue(":login", mi.data().toString());
q.exec();
q.next();
ui->leModifLogin->setText(q.value("login").toString());
ui->leModifNom->setText(q.value("nom").toString());
ui->lId->setText(q.value("id").toString());
}
La méthode data()
de l'objet mi
permet d'accéder au contenu de la ligne.
Solution
Le fichier appSgbd.pro
#-------------------------------------------------
#
# Project created by QtCreator 2016-03-17T08:19:26
#
#-------------------------------------------------
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = essaiQMYSQL
TEMPLATE = app
SOURCES += main.cpp \
cihmappsgbd.cpp
HEADERS += \
cihmappsgbd.h
FORMS += \
cihmappsgbd.ui
N'oubliez pas d'ajouter le module Qt sql
afin d'avoir accès aux classes de gestion d'un SGBD.
Le fichier cihmappsgbd.h
namespace Ui {
class CIhmAppSgbd;
}
class CIhmAppSgbd : public QMainWindow
{
Q_OBJECT
public:
explicit CIhmAppSgbd(QWidget *parent = 0);
~CIhmAppSgbd();
private slots:
void on_pbExtraire_clicked();
void on_pbAjouter_clicked();
void on_pbEffacer_clicked();
void on_pbModifier_clicked();
void onSelectLineList(QModelIndex mi);
private:
Ui::CIhmAppSgbd *ui;
QSqlDatabase db;
QStringListModel *model;
};
// MAINWINDOW_H
La méthode onSelectLineList(QModelIndex mi)
est un slot
invoqué lors du clique sur une ligne du QListView
.
Le fichier cihmappsgbd.cpp
CIhmAppSgbd::CIhmAppSgbd(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CIhmAppSgbd)
{
QSqlError err;
// init
ui->setupUi(this);
ui->lId->setVisible(false);
model=NULL;
// connexion à la bdd
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("bddFormation");
db.setUserName("user");
db.setPassword("user");
bool ok = db.open();
if (!ok) {
err = db.lastError();
qDebug() << err.text();
} else
qDebug() << "Connexion à la BDD " << ok;
// click dans zone de liste
connect(ui->lvTable, SIGNAL(clicked(QModelIndex)), this, SLOT(onSelectLineList(QModelIndex)));
}
CIhmAppSgbd::~CIhmAppSgbd()
{
delete model;
delete ui;
}
void CIhmAppSgbd::on_pbExtraire_clicked()
{
if (model != NULL)
delete model;
model = new QStringListModel(this);
QStringList liste;
QSqlQuery q(db);
q.exec("SELECT * FROM user ORDER BY nom");
while (q.next()) {
liste << q.value("login").toString();
} // for
model->setStringList(liste);
ui->lvTable->setModel(model);
}
void CIhmAppSgbd::on_pbAjouter_clicked()
{
QSqlQuery q(db);
q.prepare("INSERT INTO user VALUES (NULL, :name, :pname, :login, SHA1(:mdp))");
q.bindValue(":name", ui->leNom->text());
q.bindValue(":pname", ui->lePnom->text());
q.bindValue(":login", ui->leLogin->text());
q.bindValue(":mdp", ui->leMdp->text());
q.exec();
on_pbExtraire_clicked();
ui->leNom->clear();
ui->lePnom->clear();
ui->leLogin->clear();
ui->leMdp->clear();
}
void CIhmAppSgbd::on_pbEffacer_clicked()
{
QSqlQuery q(db);
q.prepare("DELETE FROM user WHERE id=:id");
q.bindValue(":id", ui->lId->text());
q.exec();
on_pbExtraire_clicked();
ui->leModifNom->clear();
ui->leModifLogin->clear();
ui->lId->clear();
}
void CIhmAppSgbd::on_pbModifier_clicked()
{
QSqlQuery q(db);
q.prepare("UPDATE user SET nom=:nom, login=:login WHERE id=:id");
q.bindValue(":id", ui->lId->text().toInt());
q.bindValue(":nom", ui->leModifNom->text());
q.bindValue(":login", ui->leModifLogin->text());
q.exec();
on_pbExtraire_clicked();
}
void CIhmAppSgbd::onSelectLineList(QModelIndex mi)
{
QSqlQuery q(db);
q.prepare("SELECT * FROM user WHERE login=:login");
q.bindValue(":login", mi.data().toString());
q.exec();
q.next();
ui->leModifLogin->setText(q.value("login").toString());
ui->leModifNom->setText(q.value("nom").toString());
ui->lId->setText(q.value("id").toString());
}
Le contenu du QListView
est construit de la manière suivante (voir on_pbExtraire_clicked()
) :
Construction d'un
QListString
, un objet gérant une liste de chaine de caractères.Construction d'un
QStringListModel
, un objet gérant cette liste, mais compatible avec laQListView
.Enfin la méthode
setModel()
permettant d'intégrer la liste dans le widget d'affichage.
Le fichier cihmappsgbd.ui
<ui version="4.0">
<class>CIhmAppSgbd</class>
<widget class="QMainWindow" name="CIhmAppSgbd">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1352</width>
<height>813</height>
</rect>
</property>
<property name="windowTitle">
<string>appSgbd</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QListView" name="lvTable">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>551</width>
<height>421</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pbExtraire">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>541</width>
<height>48</height>
</rect>
</property>
<property name="text">
<string>Extraire les utilisateurs</string>
</property>
</widget>
<widget class="QGroupBox" name="gbAjouter">
<property name="geometry">
<rect>
<x>650</x>
<y>30</y>
<width>651</width>
<height>421</height>
</rect>
</property>
<property name="title">
<string>Ajouter</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>290</x>
<y>60</y>
<width>348</width>
<height>211</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="leNom"/>
</item>
<item>
<widget class="QLineEdit" name="lePnom"/>
</item>
<item>
<widget class="QLineEdit" name="leLogin"/>
</item>
<item>
<widget class="QLineEdit" name="leMdp">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QPushButton" name="pbAjouter">
<property name="geometry">
<rect>
<x>120</x>
<y>330</y>
<width>391</width>
<height>48</height>
</rect>
</property>
<property name="text">
<string>Ajouter un utilisateur</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>250</width>
<height>211</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Nom : </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Prénom : </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Login : </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Mot de passe : </string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="gbModifier">
<property name="geometry">
<rect>
<x>20</x>
<y>520</y>
<width>1021</width>
<height>181</height>
</rect>
</property>
<property name="title">
<string>Modifier</string>
</property>
<widget class="QLabel" name="lId">
<property name="geometry">
<rect>
<x>700</x>
<y>140</y>
<width>161</width>
<height>39</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>30</x>
<y>60</y>
<width>160</width>
<height>101</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Nom : </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Login :</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>210</x>
<y>60</y>
<width>348</width>
<height>103</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLineEdit" name="leModifNom"/>
</item>
<item>
<widget class="QLineEdit" name="leModifLogin"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>580</x>
<y>80</y>
<width>411</width>
<height>50</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pbEffacer">
<property name="text">
<string>Effacer</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbModifier">
<property name="text">
<string>Modifier</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1352</width>
<height>44</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>