Créer un carnet de contacts avec Python, PyQt et SQLite – Real Python

By | mars 10, 2021

Formation Python

Construire des projets est sans doute l'un des moyens les plus abordables et les plus efficaces d'apprendre à programmer. Les vrais projets exigent que vous appliquiez des compétences de codage différentes et variées. Ils vous encouragent également à rechercher des sujets qui apparaissent lorsque vous résolvez des problèmes dans le processus de développement. Dans ce didacticiel, vous allez créer une application de carnet de contacts avec Python, PyQt et SQLite.

Dans ce didacticiel, vous apprendrez à:

  • Créer un interface utilisateur graphique (GUI) pour votre application de carnet de contacts utilisant Python et PyQt
  • Connectez l'application à un Base de données SQLite utilisant Prise en charge SQL de PyQt
  • Gérer les données de contact à l'aide de Architecture Model-View de PyQt

À la fin de ce projet, vous disposerez d'une application de carnet de contacts fonctionnelle qui vous permettra de stocker et de gérer vos coordonnées.

Pour obtenir le code source complet de l'application ainsi que le code de chaque étape que vous passerez dans ce didacticiel, cliquez sur le lien ci-dessous:

Démo: un carnet de contacts avec Python

Les livres de contacts sont un type d'application utile et largement utilisé. Ils sont partout. Vous avez probablement un carnet de contacts sur votre téléphone et sur votre ordinateur. Avec un carnet de contacts, vous pouvez stocker et gérer les informations de contact pour les membres de votre famille, vos amis, vos collègues, etc.

Dans ce didacticiel, vous allez coder une application d'interface graphique de carnet de contacts avec Python, SQLite et PyQt. Voici une démonstration de l'apparence et du fonctionnement de votre carnet de contacts après avoir suivi les étapes de ce didacticiel:

Votre carnet de contacts fournira l'ensemble minimal requis de fonctionnalités pour ce type d'application. Vous pourrez afficher, créer, mettre à jour et supprimer les informations de votre liste de contacts.

Aperçu du projet

Pour créer votre application de carnet de contacts, vous devez organiser le code en modules et packages et donner à votre projet une structure cohérente. Dans ce didacticiel, vous utiliserez la structure de répertoires et de fichiers suivante:

rpcontacts_project /
│
├── rpcontacts /
│ ├── __init__.py
│ ├── views.py
│ ├── database.py
│ ├── main.py
│ └── model.py
│
├── requirements.txt
├── LISEZMOI.md
└── rpcontacts.py

Voici un bref résumé du contenu de votre répertoire de projet:

  • rpcontacts_project / est le répertoire racine du projet. Il contiendra les fichiers suivants:
    • requirements.txt fournit la liste des exigences du projet.
    • LISEZMOI.md fournit des informations générales sur le projet.
    • rpcontacts.py fournit le script de point d'entrée pour exécuter l'application.
  • rpcontacts / est un sous-répertoire qui fournit le package principal de l’application. Il fournit les modules suivants:
    • __init__.py
    • views.py
    • database.py
    • main.py
    • model.py

Vous aborderez chacun de ces fichiers étape par étape dans ce didacticiel. Le nom de chaque fichier donne une idée de son rôle dans l'application. Par exemple, views.py contiendra le code pour générer l'interface graphique des fenêtres et des dialogues, database.py contiendra du code pour travailler avec la base de données, et main.py hébergera l'application elle-même. Pour terminer, model.py mettra en œuvre le modèle pour gérer les données dans la base de données de l'application.

En général, l'application aura une fenêtre principale pour afficher, ajouter, supprimer et mettre à jour les contacts. Il aura également une boîte de dialogue pour ajouter de nouveaux contacts à la base de données.

Conditions préalables

Pour tirer le meilleur parti de ce projet, une connaissance préalable de la programmation GUI avec Python et PyQt serait utile. À cet égard, vous devez connaître les principes de base pour:

  • Créez des applications GUI avec PyQt et Python
  • Construire et mettre en page des interfaces graphiques avec PyQt
  • Gérez les bases de données SQL avec Python et PyQt
  • Travailler avec des bases de données SQLite

Pour revenir sur ces sujets, vous pouvez consulter les ressources suivantes:

Ne vous inquiétez pas si vous n'êtes pas un expert dans ces domaines avant de commencer ce didacticiel. Vous apprendrez tout en mettant la main à la pâte sur un vrai projet. Si vous êtes bloqué, prenez votre temps et passez en revue les ressources liées ci-dessus. Revenez ensuite au code.

L'application de carnet de contacts que vous allez créer dans ce didacticiel a une seule dépendance externe: PyQt.

Pour suivre les meilleures pratiques dans votre processus de développement, vous pouvez commencer par créer un environnement virtuel, puis installer PyQt à l'aide de pépin. Une fois que vous avez installé PyQt, vous êtes prêt à commencer à coder!

Étape 1: Création de l'application squelette du carnet de contacts avec PyQt

Dans cette première étape, vous allez créer une application d'interface graphique PyQt minimale mais fonctionnelle pour fournir la base sur laquelle vous commencerez à créer le carnet de contacts. Vous allez également créer la structure de projet minimale requise, y compris le package principal du projet et un script de point d’entrée pour exécuter l’application.

Tous les codes et fichiers que vous ajouterez au projet de carnet de contacts dans cette section sont rassemblés sous le source_code_step_1 / annuaire. Vous pouvez les télécharger en cliquant sur le lien ci-dessous:

À la fin de cette section, vous serez en mesure d'exécuter le squelette de l'application GUI pour votre carnet de contacts pour la première fois.

Structurer le projet de carnet de contacts

Pour commencer à coder l'application, allez-y et créez un nouveau répertoire appelé rpcontacts_project /. Ce sera le répertoire racine du projet. Créez maintenant un nouveau sous-répertoire appelé rpcontacts / à l'intérieur rpcontacts_project /. Ce sous-répertoire contiendra le package principal de l'application. Enfin, lancez votre éditeur de code ou IDE dans le répertoire racine.

Pour transformer un répertoire en package, Python a besoin d'un __init__.py module pour initialiser le package. Créez ce fichier dans rpcontacts / et ajoutez-y le code suivant:

# - * - codage: utf-8 - * -

"" "Ce module fournit le package rpcontacts." ""

__version__ = «0,1,0»

Ce fichier indique à Python que rpcontacts est un paquet. Le code du fichier s'exécute lorsque vous importez le package ou certains de ses modules.

Vous n'avez pas besoin de mettre de code dans un __init__.py fichier pour initialiser le package. Un vide __init__.py fichier fera le travail. Cependant, dans ce cas, vous définissez une constante au niveau du module appelée __version__ pour contenir le numéro de version de votre application.

Création de la fenêtre principale de l’application

Il est maintenant temps de créer la fenêtre principale de votre carnet de contacts. Pour ce faire, créez un module appelé views.py dans votre rpcontacts paquet. Ajoutez ensuite le code suivant au module et enregistrez-le:

# - * - codage: utf-8 - * -

"" "Ce module propose des vues pour gérer la table des contacts." ""

de PyQt5.QtWidgets importer (
    QHBoxLayout,
    QMainWindow,
    QWidget,
)

classer La fenêtre(QMainWindow):
    """Fenêtre principale."""
    def __init__(soi, parent=Aucun):
        "" "Initialiseur." ""
        super().__init__(parent)
        soi.setWindowTitle("Contacts RP")
        soi.redimensionner(550, 250)
        soi.centralWidget = QWidget()
        soi.setCentralWidget(soi.centralWidget)
        soi.agencement = QHBoxLayout()
        soi.centralWidget.setLayout(soi.agencement)

Tout d'abord, vous importez les classes requises à partir de PyQt5.QtWidgets. Ensuite, vous créez La fenêtre. Cette classe hérite de QMainWindow et fournit le code pour générer la fenêtre principale de l'application. Dans la méthode d'initialisation, vous définissez le titre de la fenêtre sur "Contacts RP", redimensionnez la fenêtre pour 550 par 250 pixels, définissez et définissez le widget central à l'aide de QWidget, et enfin définir une disposition pour le widget central en utilisant une disposition de boîte horizontale.

Codage et exécution de l'application

Étant donné que vous disposez déjà d’une fenêtre principale pour le carnet de contacts, il est temps d’écrire le code pour créer une application PyQt fonctionnelle à l’aide de QApplication. Pour ce faire, créez un nouveau module appelé main.py dans votre rpcontacts package et ajoutez-y le code suivant:

# - * - codage: utf-8 - * -
# rpcontacts / main.py

"" "Ce module fournit l'application RP Contacts." ""

importer sys

de PyQt5.QtWidgets importer QApplication

de .views importer La fenêtre

def principale():
    "" "Fonction principale RP Contacts." ""
    # Créer l'application
    appli = QApplication(sys.argv)
    # Créer la fenêtre principale
    gagner = La fenêtre()
    gagner.Afficher()
    # Exécutez la boucle d'événements
    sys.sortir(appli.exec())

Dans ce module, vous importez sys pour avoir accès à sortir(), qui vous permet de quitter proprement l'application lorsque l'utilisateur ferme la fenêtre principale. Ensuite, vous importez QApplication de PyQt5.QtWidgets et La fenêtre de vues. La dernière étape consiste à définir principale() comme fonction principale de votre application.

À l'intérieur principale(), vous instanciez QApplication et La fenêtre. Alors tu appelles .Afficher() sur La fenêtre, et enfin vous exécutez l'application boucle principale, ou boucle d'événement, utilisant .exec ().

Accédez maintenant au répertoire racine du projet rpcontacts_project / et créez un fichier appelé rpcontacts.py. Ce fichier fournit le script de point d'entrée pour exécuter l'application. Ajoutez le code suivant au fichier et enregistrez-le:

#! / usr / bin / env python3
# - * - codage: utf-8 - * -
# rpcontacts_project / rpcontacts.py

"" "Ce module fournit un script de point d'entrée RP Contacts." ""

de rpcontacts.main importer principale

si __Nom__ == "__principale__":
    principale()

Ce fichier importe principale() de ton main.py module. Ensuite, vous implémentez l'instruction conditionnelle traditionnelle qui appelle principale() si l'utilisateur exécute ce module en tant que script Python. Maintenant, lancez l'application en exécutant la commande python rpcontacts.py dans votre environnement Python. Vous verrez la fenêtre suivante sur votre écran:

Contacter Book App Skeleton

C'est tout! Vous avez créé une application d'interface graphique PyQt minimale mais fonctionnelle que vous pouvez utiliser comme point de départ pour créer votre carnet de contacts. À ce stade, votre projet doit avoir la structure suivante:

./rpcontacts_project/
│
├── rpcontacts /
│ ├── __init__.py
│ ├── views.py
│ └── main.py
│
└── rpcontacts.py

Dans cette section, vous avez créé la structure minimale requise pour votre projet de carnet de contacts à l'aide de modules et de packages Python. Vous avez créé la fenêtre principale de l’application et assemblé le code standard pour créer une application d’interface graphique PyQt. Vous avez également exécuté l'application pour la première fois. Ensuite, vous allez commencer à ajouter des fonctionnalités à votre interface graphique.

Étape 2: création de l'interface graphique du carnet de contacts avec Python

Maintenant que vous avez créé le squelette de votre application de carnet de contacts, vous pouvez commencer à coder l'interface graphique de la fenêtre principale. À la fin de cette section, vous aurez terminé les étapes requises pour créer l'interface graphique de votre carnet de contacts à l'aide de Python et PyQt. L'interface graphique ressemblera à ceci:

Fenêtre principale du livre de contacts

Au centre de la fenêtre, vous avez une vue sous forme de tableau pour afficher votre liste de contacts. Sur le côté droit du formulaire, vous avez trois boutons:

  1. Ajouter pour ajouter un nouveau contact à la liste
  2. Effacer pour supprimer un contact sélectionné de la liste
  3. Tout effacer pour supprimer tous les contacts de la liste

Tous les codes et fichiers que vous allez ajouter ou modifier dans cette section sont collectés sous le source_code_step_2 / annuaire. Vous pouvez les télécharger en cliquant sur le lien ci-dessous:

Revenez à la views.py module et mettre à jour le code de La fenêtre pour générer l'interface graphique ci-dessus:

    1# - * - codage: utf-8 - * -
    2# rpcontacts / views.py
    3
    4"" "Ce module propose des vues pour gérer la table des contacts." ""
    5
    6de PyQt5.QtWidgets importer (
    7    QAbstractItemView,
    8    QHBoxLayout,
    9    QMainWindow,
dix    QPushButton,
11    QTableView,
12    QVBoxLayout,
13    QWidget,
14)
15
16classer La fenêtre(QMainWindow):
17    """Fenêtre principale."""
18    def __init__(soi, parent=Aucun):
19        "" "Initialiseur." ""
20        # Snip ...
21
22        soi.setupUI()
23
24    def setupUI(soi):
25        "" "Configurez l'interface graphique de la fenêtre principale." ""
26        # Créer le widget de vue de table
27        soi.table = QTableView()
28        soi.table.setSelectionBehavior(QAbstractItemView.Sélectionner des lignes)
29        soi.table.resizeColumnsToContents()
30        # Créer des boutons
31        soi.addButton = QPushButton("Ajouter...")
32        soi.deleteButton = QPushButton("Effacer")
33        soi.clearAllButton = QPushButton("Tout effacer")
34        # Disposer l'interface graphique
35        agencement = QVBoxLayout()
36        agencement.addWidget(soi.addButton)
37        agencement.addWidget(soi.deleteButton)
38        agencement.addStretch()
39        agencement.addWidget(soi.clearAllButton)
40        soi.agencement.addWidget(soi.table)
41        soi.agencement.addLayout(agencement)

Vous importez d'abord des classes PyQt supplémentaires à utiliser dans l'interface graphique. Voici quelques-unes des plus pertinentes:

  • QPushButton pour créer le Ajouter, Effacer, et Tout effacer boutons
  • QTableView pour fournir la vue sous forme de tableau qui affiche la liste des contacts
  • QAbstractItemView pour donner accès à la politique de comportement de sélection de vue de table

Dans ce code, le premier ajout à La fenêtre est un appel à .setupUI () au bout du __init __ (). Cet appel génère l'interface graphique de la fenêtre principale lorsque vous exécutez l'application.

Voici ce que contient le code .setupUI () Est-ce que:

  • Ligne 27 crée un QTableView instance pour afficher la liste des contacts.
  • Ligne 28 définit le .selectionBehavior propriété à QAbstractItemView.SelectRows. Cela garantit que lorsqu'un utilisateur clique sur une cellule de la vue tableau, la ligne complète sera sélectionnée. Les lignes de la vue tableau contiennent toutes les informations relatives à un seul contact dans la liste des contacts.
  • Lignes 31 à 33 ajoutez les trois boutons à l'interface graphique: Ajouter, Effacer, et Tout effacer. Ces boutons n'effectuent aucune action pour le moment.
  • Lignes 35 à 41 créer et définir une mise en page cohérente pour tous les widgets de l'interface graphique.

Avec ces ajouts à La fenêtre, vous pouvez réexécuter l'application. La fenêtre sur votre écran ressemblera à la fenêtre que vous avez vue au début de la section.

Dans cette section, vous avez exécuté toutes les étapes requises pour créer l'interface graphique de la fenêtre principale de votre carnet de contacts. Vous êtes maintenant prêt à commencer à travailler sur la façon dont votre application gérera et stockera vos données de contact.

Étape 3: configuration de la base de données du carnet de contacts

À ce stade, vous avez créé une application PyQt et l'interface graphique de sa fenêtre principale pour créer votre projet de carnet de contacts. Dans cette section, vous allez écrire du code pour définir la manière dont l'application se connecte à la base de données de contacts. Pour terminer cette étape, vous utiliserez SQLite pour gérer la base de données et la prise en charge SQL de PyQt pour connecter l'application à la base de données et utiliser vos données de contact.

Le code source et les fichiers que vous allez ajouter ou modifier dans cette section sont stockés sous le source_code_step_3 / annuaire. Vous pouvez les télécharger en cliquant sur le lien ci-dessous:

Tout d'abord, revenez à main.py dans le rpcontacts / répertoire et mettez à jour le code pour créer la connexion à la base de données:

# - * - codage: utf-8 - * -
# rpcontacts / main.py

"" "Ce module fournit l'application RP Contacts." ""

importer sys

de PyQt5.QtWidgets importer QApplication

de .base de données importer createConnection
de .views importer La fenêtre

def principale():
    "" "Fonction principale RP Contacts." ""
    # Créer l'application
    appli = QApplication(sys.argv)
    # Connectez-vous à la base de données avant de créer une fenêtre
    si ne pas createConnection("contacts.sqlite"):
        sys.sortir(1)
    # Créez la fenêtre principale si la connexion a réussi
    gagner = La fenêtre()
    gagner.Afficher()
    # Exécutez la boucle d'événements
    sys.sortir(appli.exec_())

Dans ce cas, vous importez d'abord createConnection () de database.py. Cette fonction contiendra du code pour créer et ouvrir une connexion à la base de données de contacts. Vous allez créer database.py et écris createConnection () dans la section suivante.

À l'intérieur principale(), la première ligne en surbrillance est une tentative de création d'une connexion à la base de données en utilisant createConnection (). Si, pour une raison quelconque, l'application ne parvient pas à créer une connexion, l'appel à sys.exit (1) fermera l'application sans créer d'élément graphique et indiquera qu'une erreur s'est produite.

Vous devez gérer la connexion de cette façon car l'application dépend de la base de données pour fonctionner correctement. Si vous ne disposez pas d'une connexion fonctionnelle, votre application ne fonctionnera pas du tout.

Cette pratique vous permet de gérer les erreurs et de fermer proprement l'application en cas de problème. Vous pourrez également présenter à l'utilisateur des informations pertinentes sur l'erreur à laquelle l'application s'est heurtée lors de la tentative de connexion à la base de données.

Une fois ces ajouts en place, il est temps de plonger dans le code de createConnection ().

Connexion à la base de données avec PyQt et SQLite

La connexion de votre application de carnet de contacts à sa base de données associée est une étape fondamentale dans le développement de l'application. Pour ce faire, vous coderez une fonction appelée createConnection (), qui créera et ouvrira une connexion à la base de données. Si la connexion réussit, la fonction retournera Vrai. Sinon, il fournira des informations sur la cause de l'échec de la connexion.

Revenez à la rpcontacts / répertoire et créez un nouveau module appelé database.py à l'intérieur. Ajoutez ensuite le code suivant à ce module:

    1# - * - codage: utf-8 - * -
    2# rpcontacts / database.py
    3
    4"" "Ce module fournit une connexion à la base de données." ""
    5
    6de PyQt5.QtWidgets importer QMessageBox
    7de PyQt5.QtSql importer Base de données QSql
    8
    9def createConnection(nom de la base de données):
dix    "" "Créez et ouvrez une connexion à la base de données." ""
11    connexion = Base de données QSql.addDatabase("QSQLITE")
12    connexion.setDatabaseName(nom de la base de données)
13
14    si ne pas connexion.ouvert():
15        QMessageBox.Attention(
16            Aucun,
17            "RP Contact",
18            F"Erreur de la base de données: connexion.lastError().texte()",
19        )
20        revenir Faux
21
22    revenir Vrai

Ici, vous importez d'abord quelques classes PyQt requises. Ensuite, vous définissez createConnection (). Cette fonction prend un argument: nom de la base de données contient le nom ou le chemin du fichier de base de données SQLite physique dans votre système de fichiers.

Voici ce que contient le code createConnection () Est-ce que:

  • Ligne 11 crée la connexion à la base de données à l'aide de QSQLITE chauffeur.
  • Ligne 12 définit le nom de fichier ou le chemin d'accès à la base de données.
  • Ligne 14 tente d'ouvrir la connexion. Si un problème survient lors de l'appel à .ouvert(), puis le si le bloc de code affiche un message d'erreur puis renvoie Faux pour indiquer que la tentative de connexion a échoué.
  • Ligne 22 Retour Vrai si la tentative de connexion réussit.

Vous avez déjà codé createConnection (). Vous pouvez maintenant écrire le code pour créer le Contacts tables de la base de données.

Création du Contacts Table

Avec la fonction qui crée et ouvre la connexion à la base de données en place, vous pouvez procéder au codage d'une fonction d'assistance pour créer le Contacts table. Vous utiliserez ce tableau pour stocker les informations sur vos contacts.

Voici le code qui implémente _createContactsTable ():

# - * - codage: utf-8 - * -
# rpcontacts / database.py

# Snip ...
de PyQt5.QtSql importer Base de données QSql, QSqlQuery

def _createContactsTable():
    "" "Créez la table des contacts dans la base de données." ""
    createTableQuery = QSqlQuery()
    revenir createTableQuery.exec(
        "" "
                                CRÉER UN TABLEAU S'IL N'EXISTE PAS des contacts (
                                                id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NON NULL,
                                                nom VARCHAR (40) NOT NULL,
                                                emploi VARCHAR (50),
                                                email VARCHAR (40) NOT NULL
                                )
                                "" "
    )

def createConnection(nom de la base de données):
    # Snip ...
    _createContactsTable()
    revenir Vrai

Ici, vous ajoutez d'abord une nouvelle importation. Vous importez QSqlQuery pour exécuter et manipuler des instructions SQL.

À l'intérieur _createContactsTable (), vous créez un QSqlQuery exemple. Alors tu appelles .exec () sur l'objet de requête avec un SQL basé sur une chaîne CRÉER UNE TABLE déclaration comme argument. Cette instruction crée une nouvelle table appelée Contacts dans votre base de données. Le tableau comprend les colonnes suivantes:

Colonne Teneur
identifiant Un entier avec la clé primaire de la table
Nom Une chaîne avec le nom d'un contact
travail Une chaîne avec l'intitulé du poste d'un contact
e-mail Une chaîne avec l'e-mail d'un contact

Le Contacts table dans votre base de données stockera des informations pertinentes sur vos contacts.

La dernière étape pour terminer le codage database.py consiste à ajouter un appel à _createContactsTable () de l'Intérieur createConnection (), juste avant le dernier revenir déclaration. Cela garantit que l'application crée le Contacts table avant d'effectuer toute opération sur la base de données.

Une fois que vous avez créé le Contacts table, vous pouvez exécuter des tests sur la base de données et également ajouter des exemples de données pour des tests supplémentaires.

Test de la base de données du carnet de contacts

Jusqu'à présent, vous avez terminé d'écrire le code requis pour gérer la connexion à la base de données du carnet de contacts. Dans cette section, vous allez effectuer des tests pour vous assurer que ce code et la base de données elle-même fonctionnent correctement. Vous allez également ajouter des exemples de données à la base de données pour effectuer des tests supplémentaires plus tard dans ce didacticiel.

Ouvrez maintenant un terminal ou une ligne de commande et accédez au répertoire racine du projet, rpcontacts_project /. Une fois sur place, lancez une session interactive Python et saisissez le code suivant:

>>>

>>> de rpcontacts.database importer createConnection

>>> # Créer une connexion
>>> createConnection("contacts.sqlite")
Vrai

>>> # Confirmez que la table des contacts existe
>>> de PyQt5.QtSql importer Base de données QSql
>>> db = Base de données QSql.base de données()
>>> db.les tables()
['contacts', 'sqlite_sequence']

Ici, vous importez d'abord createConnection () du database.py module. Ensuite, vous appelez cette fonction pour créer et ouvrir une connexion à la base de données de contacts. Le nom de fichier de la base de données est contacts.sqlite. Étant donné que ce fichier n’existe pas dans le répertoire racine du projet, SQLite le crée pour vous. Vous pouvez vérifier cela en jetant un œil à votre répertoire actuel.

Ensuite, vous confirmez que la base de données contient une table appelée Contacts. Pour ce faire, vous appelez .base de données() sur Base de données QSql. Cette méthode de classe renvoie un pointeur vers la connexion à la base de données actuelle. Avec cette référence à la connexion, vous pouvez appeler .les tables() pour obtenir la liste des tables de la base de données. Notez que le premier tableau de la liste est Contacts, alors maintenant vous êtes sûr que tout fonctionne bien.

Vous pouvez maintenant préparer une requête SQL pour insérer des exemples de données dans le Contacts table:

>>>

>>> # Préparer une requête pour insérer des exemples de données
>>> de PyQt5.QtSql importer QSqlQuery

>>> insertDataQuery = QSqlQuery()
>>> insertDataQuery.préparer(
...     "" "
...                 INSÉRER DANS les contacts (
...                                 Nom,
...                                 travail,
...                                 e-mail
...                 )
...                 VALEURS (?, ?, ?)
...                 "" "
... )
Vrai

La requête ci-dessus vous permet d'insérer des valeurs spécifiques dans le Nom, travail, et e-mail attributs et pour enregistrer ces valeurs dans la base de données. Vous trouverez ci-dessous un exemple de procédure:

>>>

>>> # Exemple de données
>>> Les données = [[[[
...     («Linda», "Responsable technique", "linda@example.com"),
...     («Joe», "Développeur Web Senior", "joe@example.com"),
...     («Lara», "Chef de projet", "lara@example.com"),
...     ("David", "Analyste de données", "david@example.com"),
...     ("Jeanne", "Développeur Python senior", "jane@example.com"),
... ]

>>> # Insérer des exemples de données
>>> pour Nom, travail, e-mail dans Les données:
...     insertDataQuery.addBindValue(Nom)
...     insertDataQuery.addBindValue(travail)
...     insertDataQuery.addBindValue(e-mail)
...     insertDataQuery.exec()
...
Vrai
Vrai
Vrai
Vrai
Vrai

Dans ce morceau de code, vous définissez d'abord Les données pour contenir les informations de contact d'une liste de personnes. Ensuite, vous utilisez un pour boucle pour insérer les données en appelant .addBindValue (). Alors tu appelles .exec () sur l'objet de requête pour exécuter efficacement la requête SQL sur la base de données.

Depuis tous les appels à .exec () revenir Vrai, vous pouvez conclure que les données ont été insérées avec succès dans la base de données. Si vous souhaitez confirmer cela, exécutez le code suivant:

>>>

>>> mettre en doute = QSqlQuery()
>>> mettre en doute.exec("CHOISIR le nom, le poste, l'adresse e-mail FROM contacts")
Vrai

>>> tandis que mettre en doute.suivant():
...     impression(mettre en doute.évaluer(0), mettre en doute.évaluer(1), mettre en doute.évaluer(2))
...
Linda Responsable technique linda@example.com
Joe Développeur Web senior joe@example.com
Chef de projet Lara lara@example.com
David Data Analyst david@example.com
Jane Développeur Python senior jane@example.com

C'est tout! Votre base de données fonctionne très bien! Vous disposez à présent de quelques exemples de données pour tester l'application, et vous pouvez vous concentrer sur la manière de charger et d'afficher les informations de contact dans la fenêtre principale de votre carnet de contacts.

Étape 4: Affichage et mise à jour des contacts existants

Pour afficher vos coordonnées dans la fenêtre principale de l'application, vous pouvez utiliser QTableView. Cette classe fait partie de l'architecture Model-View de PyQt et fournit un moyen robuste et efficace d'afficher des éléments à partir d'un objet de modèle PyQt.

Les fichiers et le code que vous allez ajouter ou modifier dans cette section sont stockés sous le source_code_step_4 / annuaire. Pour les télécharger, cliquez sur le lien ci-dessous:

Une fois cette étape terminée, votre carnet de contacts ressemblera à ceci:

Contact Book Visualiser les données

L'objet de vue de table dans la fenêtre principale fournit la fonctionnalité requise pour vous permettre de modifier et de mettre à jour rapidement les informations de contact.

Par exemple, pour mettre à jour le nom d'un contact, vous pouvez double-cliquer sur la cellule contenant le nom, mettre à jour le nom, puis appuyer sur Entrer pour enregistrer automatiquement les modifications dans la base de données. Mais avant de pouvoir le faire, vous devez créer un modèle et le connecter à la vue de table.

Création d'un modèle pour gérer les données de contact

PyQt fournit un ensemble complet de classes pour travailler avec des bases de données SQL. Pour votre application de carnet de contacts, vous utiliserez QSqlTableModel, qui fournit un modèle de données modifiable pour une seule table de base de données. Il est parfait pour le travail puisque votre base de données contient une seule table, Contacts.

Revenez à votre éditeur de code et créez un nouveau module appelé model.py à l'intérieur de rpcontacts / annuaire. Ajoutez le code suivant au fichier et enregistrez-le:

    1# - * - codage: utf-8 - * -
    2# rpcontacts / model.py
    3
    4"" "Ce module fournit un modèle pour gérer la table des contacts." ""
    5
    6de PyQt5.QtCore importer Qt
    7de PyQt5.QtSql importer QSqlTableModel
    8
    9classer ContactsModèle:
dix    def __init__(soi):
11        soi.maquette = soi._createModel()
12
13    @staticmethod
14    def _createModel():
15        "" "Créez et configurez le modèle." ""
16        tableModèle = QSqlTableModel()
17        tableModèle.setTable("Contacts")
18        tableModèle.setEditStrategy(QSqlTableModel.OnFieldChange)
19        tableModèle.sélectionner()
20        en-têtes = ("IDENTIFIANT", "Nom", "Travail", "E-mail")
21        pour columnIndex, entête dans énumérer(en-têtes):
22            tableModèle.setHeaderData(columnIndex, Qt.Horizontal, entête)
23        revenir tableModèle

Dans ce code, vous effectuez d'abord les importations requises, puis vous créez ContactsModèle. Dans l'initialiseur de classe, vous définissez un attribut d'instance appelé .maquette pour contenir le modèle de données.

Ensuite, vous ajoutez une méthode statique pour créer et configurer l'objet de modèle. Voici ce que contient le code ._createModel () Est-ce que:

  • Ligne 16 crée une instance de QSqlTableModel () appelé tableModèle.
  • Ligne 17 associe l'objet modèle avec le Contacts table dans votre base de données.
  • Ligne 18 définit le .editStrategy propriété du modèle à QSqlTableModel.OnFieldChange. Avec cela, vous vous assurez que les modifications sur le modèle sont enregistrées immédiatement dans la base de données.
  • Ligne 19 charge la table dans le modèle en appelant .sélectionner().
  • Lignes 20 à 22 définir et définir des en-têtes conviviaux pour le Contacts colonnes du tableau.
  • Ligne 23 renvoie le modèle nouvellement créé.

À ce stade, votre modèle de données est prêt à être utilisé. Vous devez maintenant connecter le widget de vue de table au modèle afin de pouvoir présenter à vos utilisateurs les informations de contact.

Connexion du modèle à la vue

Pour afficher les données de contact dans la fenêtre principale de votre carnet de contacts, vous devez connecter la vue sous forme de tableau au modèle de données. Pour effectuer cette connexion, vous devez appeler .setModel () sur l'objet vue table et passez le modèle en argument:

# - * - codage: utf-8 - * -
# rpcontacts / views.py

# Snip ...
de .maquette importer ContactsModèle

classer La fenêtre(QMainWindow):
    """Fenêtre principale."""
    def __init__(soi, parent=Aucun):
        # Snip ...
        soi.contactsModèle = ContactsModèle()
        soi.setupUI()

    def setupUI(soi):
        "" "Configurez l'interface graphique de la fenêtre principale." ""
        # Créer le widget de vue de table
        soi.table = QTableView()
        soi.table.setModel(soi.contactsModèle.maquette)
        soi.table.setSelectionBehavior(QAbstractItemView.Sélectionner des lignes)
        # Snip ...

Dans ce code, vous importez d'abord ContactsModèle de model.py. Cette classe fournit le modèle qui gère les données de votre base de données de contacts.

Dans l'initialiseur de La fenêtre, vous créez une instance de ContactsModèle. Puis à l'intérieur .setupUI (), tu appelles .setModel () sur .table pour connecter le modèle à la vue de table. Si vous exécutez l'application après cette mise à jour, vous obtiendrez la fenêtre que vous avez vue au début de l'étape 4.

Affichage et mise à jour des contacts

L’architecture Model-View de PyQt offre un moyen robuste et convivial de créer des applications GUI qui gèrent les bases de données. Des modèles communiquer et accéder aux données de la base de données. Tout changement dans un modèle met immédiatement à jour la base de données. Vues sont responsables de l'affichage des données à l'utilisateur et également de la fourniture de widgets modifiables pour permettre à l'utilisateur de modifier les données directement dans la vue.

Si l'utilisateur modifie les données via la vue, la vue communique en interne avec et met à jour le modèle, ce qui enregistre les modifications dans la base de données physique:

Contact Book Visualiser les données de mise à jour

Dans cet exemple, vous double-cliquez sur Joe's Travail domaine. Cela vous donne accès à un widget modifiable qui vous permet de modifier la valeur dans la cellule. Ensuite, vous mettez à jour la description de poste à partir de Développeur Web senior à Développeur web. Quand tu frappes Entrer, la vue de table communique la modification au modèle et le modèle enregistre immédiatement la modification dans la base de données.

Pour confirmer que les modifications ont bien été enregistrées dans la base de données, vous pouvez fermer l'application et l'exécuter à nouveau. La vue du tableau doit refléter vos mises à jour.

Étape 5: Création de nouveaux contacts

À cette étape, votre application de carnet de contacts fournit des fonctionnalités pour charger, afficher et mettre à jour les informations sur vos contacts. Même si vous pouvez modifier et mettre à jour les informations de contact, vous ne pouvez ni ajouter ni supprimer des contacts de la liste.

Tous les fichiers et le code que vous allez ajouter ou modifier dans cette section sont rassemblés dans le source_code_step_5 / annuaire. Pour les télécharger, cliquez sur le lien ci-dessous:

Dans cette section, vous fournirez la fonctionnalité requise pour ajouter de nouveaux contacts à la base de données, en utilisant une boîte de dialogue contextuelle pour saisir les nouvelles informations. La première étape consiste à créer le Ajouter le contact dialogue.

Création de la boîte de dialogue Ajouter un contact

Les boîtes de dialogue sont de petites fenêtres que vous pouvez utiliser pour communiquer avec vos utilisateurs. Dans cette section, vous coderez le carnet de contacts Ajouter le contact pour permettre à vos utilisateurs d'ajouter de nouveaux contacts à leur liste actuelle de contacts.

Pour coder le Ajouter le contact boîte de dialogue, vous sous-classerez QDialog. Cette classe fournit un plan pour créer des boîtes de dialogue pour vos applications GUI.

Ouvrez maintenant le views.py module et mettez à jour la section d'importation comme ceci:

# - * - codage: utf-8 - * -
# rpcontacts / views.py

# Snip ...
de PyQt5.QtCore importer Qt
de PyQt5.QtWidgets importer (
    QAbstractItemView,
    QDialog,
    QDialogButtonBox,
    QFormLayout,
    QHBoxLayout,
    QLineEdit,
    QMainWindow,
    QMessageBox,
    QPushButton,
    QTableView,
    QVBoxLayout,
    QWidget,
)

Les lignes en surbrillance dans le code ci-dessus importent les classes requises pour construire le Ajouter le contact dialogue. Avec ces classes dans votre espace de noms, ajoutez la classe suivante à la fin de views.py:

    1# - * - codage: utf-8 - * -
    2# rpcontacts / views.py
    3
    4# Snip ...
    5classer AddDialog(QDialog):
    6    "" "Boîte de dialogue Ajouter un contact." ""
    7    def __init__(soi, parent=Aucun):
    8        "" "Initialiseur." ""
    9        super().__init__(parent=parent)
dix        soi.setWindowTitle("Ajouter le contact")
11        soi.agencement = QVBoxLayout()
12        soi.setLayout(soi.agencement)
13        soi.Les données = Aucun
14
15        soi.setupUI()
16
17    def setupUI(soi):
18        "" "Configurez l'interface graphique de la boîte de dialogue Ajouter un contact." ""
19        # Créer des modifications de ligne pour les champs de données
20        soi.nameField = QLineEdit()
21        soi.nameField.setObjectName("Nom")
22        soi.domaine d'emploi = QLineEdit()
23        soi.domaine d'emploi.setObjectName("Travail")
24        soi.emailField = QLineEdit()
25        soi.emailField.setObjectName("E-mail")
26        # Disposer les champs de données
27        agencement = QFormLayout()
28        agencement.ajouter une rangée("Nom:", soi.nameField)
29        agencement.ajouter une rangée("Travail:", soi.domaine d'emploi)
30        agencement.ajouter une rangée("E-mail:", soi.emailField)
31        soi.agencement.addLayout(agencement)
32        # Ajoutez des boutons standard à la boîte de dialogue et connectez-les
33        soi.boutonsBox = QDialogButtonBox(soi)
34        soi.boutonsBox.setOrientation(Qt.Horizontal)
35        soi.boutonsBox.setStandardButtons(
36            QDialogButtonBox.D'accord | QDialogButtonBox.Annuler
37        )
38        soi.boutonsBox.accepté.relier(soi.J'accepte)
39        soi.boutonsBox.rejeté.relier(soi.rejeter)
40        soi.agencement.addWidget(soi.boutonsBox)

Il se passe beaucoup de choses dans ce code. Voici un résumé:

  • Ligne 5 définit une nouvelle classe qui hérite de QDialog.
  • Lignes 7 à 15 définir l'initialiseur de classe. Dans ce cas, l'ajout le plus pertinent est .Les données, qui est un attribut d'instance que vous utiliserez pour conserver les données fournies par vos utilisateurs.

Dans .setupUI (), vous définissez l'interface graphique de la boîte de dialogue:

  • Lignes 20 à 25 ajouter trois QLineEdit objets: Nom, travail, et e-mail. Vous utiliserez ces modifications de ligne pour prendre les entrées de l'utilisateur pour le nom, la description de poste et l'adresse e-mail du contact à ajouter. Ils représentent les champs correspondants dans la base de données.
  • Lignes 27 à 30 créer un QFormLayout instance qui organise les modifications de ligne dans un formulaire. Ce gestionnaire de mise en page fournit également des étiquettes conviviales pour chaque modification de ligne ou champ.
  • Lignes 33 à 37 ajouter un QDialogButtonBox objet qui fournit deux boutons standard: d'accord et Annuler. Le d'accord accepte l'entrée de l'utilisateur et le Annuler le bouton le rejette.
  • Lignes 38 et 39 connecter la boîte de dialogue intégrée .accepté() et .rejeté() signaux avec le .J'accepte() et rejeter() slots, respectivement. Dans ce cas, vous vous fiez à la boîte de dialogue intégrée .rejeter() slot, qui ferme la boîte de dialogue sans traiter l'entrée. En dehors de cela, il vous suffit de coder le .J'accepte() fente.

Pour coder la boîte de dialogue .J'accepte() emplacement, vous devez tenir compte du fait que toute entrée utilisateur a besoin validation pour vous assurer qu'il est correct et sûr. Cela est particulièrement vrai lorsque vous travaillez avec des bases de données SQL en raison du risque d'attaque par injection SQL.

Dans cet exemple, vous allez ajouter une règle de validation minimale juste pour vous assurer que l'utilisateur fournit des données pour chaque champ de saisie dans la boîte de dialogue. Cependant, ajouter vos propres règles de validation plus robustes serait un bon exercice.

Sans plus tarder, revenez à AddDialog et ajoutez le code suivant pour son .J'accepte() fente:

    1# - * - codage: utf-8 - * -
    2# rpcontacts / views.py
    3
    4# Snip ...
    5classer AddDialog(QDialog):
    6    def __init__(soi, parent=Aucun):
    7        # Snip ...
    8
    9    def setupUI(soi):
dix        # Snip ...
11
12    def J'accepte(soi):
13        "" "Acceptez les données fournies via la boîte de dialogue." ""
14        soi.Les données = []
15        pour domaine dans (soi.nameField, soi.domaine d'emploi, soi.emailField):
16            si ne pas domaine.texte():
17                QMessageBox.critique(
18                    soi,
19                    "Erreur!",
20                    F"You must provide a contact's field.objectName()",
21                )
22                soi.Les données = Aucun  # Reset .data
23                return
24
25            soi.Les données.ajouter(field.texte())
26
27        si ne pas soi.Les données:
28            return
29
30        super().accept()

The code within .accept() does the following:

  • Line 14 initializes .data to an empty list ([]). This list will store the user’s input data.
  • Line 15 defines a pour loop that iterates over the three line edits, or fields, in the dialog.
  • Lines 16 to 23 define a conditional statement that checks if the user has provided data for each field in the dialog. If not, then the dialog shows an error message that warns the user about the missing data.
  • Line 25 adds the user’s input for each field to .data.
  • Line 30 calls the superclass’s .accept() slot to provide the standard behavior that closes the dialog after the user clicks d'accord.

With this code, you’re ready to add a new slot to the contact book’s main window. This slot will launch the dialog, and if the user provides valid input, then the slot will use the model to save the newly added contact to the database.

Launching the Add Contact Dialog

Now that you’ve coded the Add Contact dialog, it’s time to add a new slot to Window so you can launch the dialog by clicking Add and process the user’s input once they click d'accord.

Go to the definition of Window and add the following code:

    1# -*- coding: utf-8 -*-
    2# rpcontacts/views.py
    3
    4# Snip...
    5classer Window(QMainWindow):
    6    # Snip...
    7
    8    def setupUI(soi):
    9        # Snip...
dix        soi.addButton = QPushButton("Add...")
11        soi.addButton.clicked.connect(soi.openAddDialog)
12        # Snip...
13
14    def openAddDialog(soi):
15        """Open the Add Contact dialog."""
16        dialog = AddDialog(soi)
17        si dialog.exec() == QDialog.Accepté:
18            soi.contactsModel.addContact(dialog.Les données)
19            soi.table.resizeColumnsToContents()

Here’s a summary of what’s happening in the above code:

  • Line 11 connects the .clicked() signal of the Add button to the newly created slot, .openAddDialog(). This way, a click on the button will automatically call the slot.
  • Line 14 defines the .openAddDialog() slot.
  • Line 16 creates an instance of AddDialog.
  • Lines 17 to 19 define a conditional statement to check if the dialog was accepted. If so, then line 14 calls .addContact() on the data model with the dialog’s .data attribute as an argument. The final statement in the si code block resizes the table view to fit the size of its updated content.

Now that you have a way to launch the Add Contact dialog and to process its data, you need to provide the code for .addContact() in your data model. That’s a topic for the next section.

Processing the Add Dialog’s Data in the Model

In this section, you’ll add a method called .addContact() to your data model, ContactsModel. Ouvert model.py in your code editor, go to the definition of ContactsModel, and add the following code:

    1# -*- coding: utf-8 -*-
    2# rpcontacts/model.py
    3
    4# Snip...
    5classer ContactsModel:
    6    # Snip...
    7
    8    def addContact(soi, Les données):
    9        """Add a contact to the database."""
dix        rows = soi.maquette.rowCount()
11        soi.maquette.insertRows(rows, 1)
12        pour column, field dans énumérer(Les données):
13            soi.maquette.setData(soi.maquette.indice(rows, column + 1), field)
14        soi.maquette.submitAll()
15        soi.maquette.select()

À l'intérieur .addContact(), the code does the following:

  • Line 10 gets the current number of rows in the data model.
  • Line 11 inserts a new row at the end of the data model.
  • Lines 12 and 13 run a pour loop that inserts every item in Les données into the corresponding cell in the data model. To do this, line 9 calls .setData() on the model, with the index of the cell and the current data field as arguments.
  • Line 14 submits the changes to the database by calling .submitAll() on the model.
  • Line 15 reloads the data from the database into the model.

If you run the application with these new additions, then you’ll get the following behavior:

Contact Book Add Contact

Now when you click Add, le Add Contact dialog appears on your screen. You can use the dialog to provide the required information for a new contact and to add the contact to the database by clicking d'accord.

Step 6: Deleting Existing Contacts

The final feature you’ll add to the contact book application is the ability to remove contacts from the database using the GUI.

Again, you’ll find all the files and the code added or modified in this section under the source_code_step_6/ directory. You can download them by clicking the link below:

In this section, you’ll first add the capability to delete a single contact at a time. Then you’ll add code to remove all the contacts from the database.

Deleting Selected Contacts

To remove a single contact from the contact database, you need to select the desired contact in the table view on the contact book’s main window. Once you’ve selected the contact, you can click Delete to perform the operation on the database.

Aller à la model.py module and add the following code to implement .deleteContact() inside ContactsModel:

# -*- coding: utf-8 -*-
# rpcontacts/model.py

# Snip...
classer ContactsModel:
    # Snip...

    def deleteContact(soi, row):
        """Remove a contact from the database."""
        soi.maquette.removeRow(row)
        soi.maquette.submitAll()
        soi.maquette.select()

This method has three lines of code. The first line removes the selected row. The second line submits the change to the database. Finally, the third line reloads the data into the model.

Next, get back to the views.py module and add the code behind the Delete button in Window:

# -*- coding: utf-8 -*-
# rpcontacts/views.py

# Snip...
classer Window(QMainWindow):
    # Snip...

    def setupUI(soi):
        """Setup the main window's GUI."""
        # Snip...
        soi.deleteButton = QPushButton("Delete")
        soi.deleteButton.clicked.connect(soi.deleteContact)
        # Snip...

    def deleteContact(soi):
        """Delete the selected contact from the database."""
        row = soi.table.currentIndex().row()
        si row < 0:
            return

        messageBox = QMessageBox.warning(
            soi,
            "Warning!",
            "Do you want to remove the selected contact?",
            QMessageBox.D'accord | QMessageBox.Annuler,
        )

        si messageBox == QMessageBox.D'accord:
            soi.contactsModel.deleteContact(row)

In the first highlighted line, you connect the .clicked() signal of the Delete button to the .deleteContact() slot. This connection triggers a call to .deleteContact() every time the user clicks the button.

Dans .deleteContact(), you first get the index of the currently selected row in the table view. Le si statement checks if the index is lower than 0, which would mean that there are no contacts in the table view. If so, then the method returns immediately without performing any further actions.

Then the method shows a warning message confirming that the user wants to delete the selected contact. If the user accepts the operation, then .deleteContact(row) gets called. In this case, row represents the index of the currently selected row in the table.

After these additions, you can run the application again to get the following behavior:

Contact Book Delete Contact

Now when you select a contact from the table view and click Delete, you’re presented with a warning message. If you click the message dialog’s d'accord button, then the application removes the selected contact from the database, updating the table view accordingly.

Clearing the Contact Database

To remove all the contacts from the database, you’ll start by adding a method called .clearContacts() à ContactsModel. Open your model.py module and add the following method at the end of the class:

    1# -*- coding: utf-8 -*-
    2# rpcontacts/model.py
    3
    4# Snip...
    5classer ContactsModel:
    6    # Snip...
    7
    8    def clearContacts(soi):
    9        """Remove all contacts in the database."""
dix        soi.maquette.setEditStrategy(QSqlTableModel.OnManualSubmit)
11        soi.maquette.removeRows(0, soi.maquette.rowCount())
12        soi.maquette.submitAll()
13        soi.maquette.setEditStrategy(QSqlTableModel.OnFieldChange)
14        soi.maquette.select()

Here’s what each line of code does:

  • Line 10 sets the data model’s .editStrategy property to QSqlTableModel.OnManualSubmit. This allows you to cache all the changes until you call .submitAll() later on. You need to do this because you’re changing several rows at the same time.
  • Line 11 removes all the rows from the model.
  • Line 12 saves changes to the database.
  • Ligne 13 resets the model’s .editStrategy property to its original value, QSqlTableModel.OnFieldChange. If you don’t reset this property to its original value, then you won’t be able to update the contacts directly in the table view.
  • Line 14 reloads the data into the model.

Once you’ve coded .clearContacts(), you can get back to the views.py file and update Window with the following code:

# -*- coding: utf-8 -*-
# rpcontacts/views.py

# Snip...
classer Window(QMainWindow):
    # Snip...

    def setupUI(soi):
        """Setup the main window's GUI."""
        # Snip...
        soi.clearAllButton = QPushButton("Clear All")
        soi.clearAllButton.clicked.connect(soi.clearContacts)
        # Snip...

    def clearContacts(soi):
        """Remove all contacts from the database."""
        messageBox = QMessageBox.warning(
            soi,
            "Warning!",
            "Do you want to remove all your contacts?",
            QMessageBox.D'accord | QMessageBox.Annuler,
        )

        si messageBox == QMessageBox.D'accord:
            soi.contactsModel.clearContacts()

The first highlighted line in this code connects the .clicked() signal of the Clear All button to the .clearContacts() slot below.

Dans .clearContacts(), you first create a message dialog, messageBox, to ask the user to confirm the removing operation. If the user confirms the operation by clicking d'accord, alors .clearContacts() gets called on the model to remove all the contacts from the database:

Contact Book Clear All Contacts

That’s it! With this last piece of code, your contact book application is complete. The application provides features that allow your users to display, add, update, and remove contacts from the database.

Conclusion

Building a contact book GUI application with Python, PyQt, and SQLite is an excellent exercise for you to expand your skills with these tools and as a developer in general. Coding projects like this allows you to apply the knowledge and skills you already have and also pushes you to research and learn about new topics every time you encounter a new programming problem.

In this tutorial, you learned how to:

  • Build the GUI for a contact book application using PyQt
  • Use PyQt’s SQL support to connect the application to an SQLite database
  • Use PyQt’s Model-View architecture to work with the application’s database

You can download the complete source code for the contact book application and also the code to complete each step in this tutorial by clicking the link below:

Next Steps

At this point, you’ve completed a fully functional contact book project. The application provides minimal functionality, but it’s a good starting point to continue adding features and take your Python and PyQt skills to the next level. Here are some next step ideas that you can implement:

  • Add new data fields: Adding new data fields to store more information about your contacts would be great. For example, you can add the contact’s photo, phone number, web page, Twitter handle, and so on. To do this, you might need to create new tables and set up relations between them. PyQt provides the QSqlRelationalTableModel, which defines an editable data model for a single table and provides foreign key support.

  • Provide search capability: Giving your users a way to search for a contact in the database is arguably a must-have feature in this kind of application. To implement it, you can use PyQt’s QSqlQuery et QSqlQueryModel.

  • Add back-up capability: Providing a way of backing up contact information is another interesting feature. Users might face problems with their computers and lose their data. You can provide options to upload the data to a cloud service or to back it up to an external disk.

These are just a few ideas for how you can continue adding features to your contact book. Take the challenge and build something amazing on top of this!

[ad_2]