Dans ce chapitre, nous allons voir les possibilités pour rechercher des contacts dans le carnet d'adresse.
Plus nous ajoutons des contacts dans l'application, plus il devient difficile de naviguer avec les boutons 下一 et 上一 . Dans ce cas, une fonction de recherche serait plus efficace pour rechercher les contacts. La capture d'écran ci-dessus montre le bouton de recherche Find et sa position dans le paneau de bouton.
Lorsque l'utilisateur clique sur le bouton
Find
, il est courant d'afficher une boîte de dialogue qui demande à l'utilisateur d'entrer un nom de contact. Qt fournit la classe
QDialog
, que nous sous-classons dans ce chapitre pour implémenter la class
FindDialog
.
Pour sous-classer
QDialog
, nous commençons par inclure le header de
QDialog
dans le fichier
finddialog.h
. De plus, nous déclarons les classes
QLineEdit
et
QPushButton
car nous utilisons ces widgets dans notre classe dialogue.
Tout comme dans la classe
AddressBook
, la classe
FindDialog
utilise la macro
Q_OBJECT
et son constructeur est défini de façon à accepter un
QWidget
parent, même si cette boîte de dialogue sera affichée dans une fenêtre séparée.
#include <QDialog> class QLineEdit; class QPushButton; class FindDialog : public QDialog { Q_OBJECT public: FindDialog(QWidget *parent = 0); QString getFindText(); public slots: void findClicked(); private: QPushButton *findButton; QLineEdit *lineEdit; QString findText; };
Nous définissons la méthode publique
getFindText()
pour être utilisée par les classes qui instancient
FindDialog
, ce qui leur permet d'obtenir le texte entré par l'utilisateur. Un slot public,
findClicked()
, est défini pour prendre en charge le texte lorsque l'utilisateur clique sur le bouton
Find
.
Finalement, nous définissons les variables privées
findButton
,
lineEdit
et
findText
, qui correspondent respectivement au bouton
Find
, au champ de texte dans lequel l'utilisateur tape le texte à rechercher, et à une variable interne stockant le texte pour une utilisation ultérieure.
Dans le constructeur de
FindDialog
, nous instancions les objets des variables privées
lineEdit
,
findButton
et
findText
. Nous utilisons ensuite un
QHBoxLayout
pour positionner les widgets.
FindDialog::FindDialog(QWidget *parent) : QDialog(parent) { QLabel *findLabel = new QLabel(tr("Enter the name of a contact:")); lineEdit = new QLineEdit; findButton = new QPushButton(tr("&Find")); findText = ""; QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(findLabel); layout->addWidget(lineEdit); layout->addWidget(findButton); setLayout(layout); setWindowTitle(tr("Find a Contact")); connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); connect(findButton, SIGNAL(clicked()), this, SLOT(accept())); }
Nous mettons en place la mise en page et le titre de la fenêtre, et nous connectons les signaux aux slots. Remarquez que le signal
clicked()
de
findButton
est connecté à
findClicked()
et
accept()
. Le slot
accept()
fourni par le
QDialog
ferme la boîte de dialogue et lui donne le code de retour
接受
. Nous utilisons cette fonction pour aider la méthode
findContact()
de la classe
AddressBook
à savoir si l'objet
FindDialog
a été fermé. Ceci sera expliqué plus loin lorsque nous verrons la méthode
findContact()
.
Dans
findClicked()
, nous validons le champ de texte pour nous assurer que l'utilisateur n'a pas cliqué sur le bouton
Find
sans avoir entré un nom de contact. Ensuite, nous stockons le texte du champ d'entrée
lineEdit
dans
findText
. Et finalement nous vidons le contenu de
lineEdit
et cachons la boîte de dialogue.
void FindDialog::findClicked() { QString text = lineEdit->text(); if (text.isEmpty()) { QMessageBox::information(this, tr("Empty Field"), tr("Please enter a name.")); return; } else { findText = text; lineEdit->clear(); hide(); } }
La variable
findText
a un accesseur publique associé:
getFindText()
. Étant donné que nous ne modifions
findText
directement que dans le constructeur et la méthode
findClicked()
, nous ne créons pas de manipulateurs associé à
getFindText()
. Puisque
getFindText()
est publique, les classes instanciant et utilisant
FindDialog
peuvent toujours accéder à la chaîne de caractères que l'utilisateur a entré et accepté.
QString FindDialog::getFindText() { return findText; }
Pour utiliser
FindDialog
depuis la classe
AddressBook
, nous incluons
finddialog.h
dans le fichier
addressbook.h
.
#include "finddialog.h"
Jusqu'ici, toutes les fonctionnalités du carnet d'adresses ont un
QPushButton
et un slot correspondant. De la même façon, pour la fonctionnalité
Find
, nous avons
findButton
et
findContact()
.
Le
findButton
est déclaré comme une variable privée et la méthode
findContact()
est déclarée comme un slot public.
void findContact();
...
QPushButton *findButton;
Finalement, nous déclarons la variable privée
dialog
que nous allons utiliser pour accéder à une instance de
FindDialog
.
FindDialog *dialog;
Une fois que nous avons instancié la boîte de dialogue, nous voulons l'utiliser plus qu'une fois. Utiliser une variable privée nous permet d'y référer à plus d'un endroit dans la classe.
Dans le constructeur de
AddressBook
, nous instancions nos objets privés,
findbutton
et
findDialog
:
findButton = new QPushButton(tr("&Find"));
findButton->setEnabled(false);
...
dialog = new FindDialog;
Ensuite, nous connectons le signal
clicked()
de
findButton
à
findContact()
.
connect(findButton, SIGNAL(clicked()), this, SLOT(findContact()));
Maintenant, tout ce qui manque est le code de notre méthode
findContact()
:
void AddressBook::findContact() { dialog->show(); if (dialog->exec() == QDialog::Accepted) { QString contactName = dialog->getFindText(); if (contacts.contains(contactName)) { nameLine->setText(contactName); addressText->setText(contacts.value(contactName)); } else { QMessageBox::information(this, tr("Contact Not Found"), tr("Sorry, \"%1\" is not in your address book.").arg(contactName)); return; } } updateInterface(NavigationMode); }
Nous commençons par afficher l'instance de
FindDialog
,
dialog
. L'utilisateur peut alors entrer le nom du contact à rechercher. Lorsque l'utilisateur clique sur le bouton
findButton
, la boîte de dialogue est masquée et le code de retour devient
QDialog::Accepted
. Ce code de retour vient remplir la condition du premier if.
Ensuite, nous extrayons le texte que nous utiliserons pour la recherche, il s'agit ici de
contactName
obtenu à l'aide de la méthode
getFindText()
de
FindDialog
. Si le contact existe dans le carnet d'adresse, nous l'affichons directement. Sinon, nous affichons le
QMessageBox
suivant pour indiquer que la recherche à échouée.
文件: