Describes how to add a find function.
Here we look at ways to locate contacts and addresses in the address book.
					As we add contacts to our address book, it becomes tedious to navigate the list with the 下一 and 上一 buttons. A Find function would be more efficient. The screenshot above shows the Find button and its position on the panel of buttons.
						When the user clicks on the
						
							Find
						
						button, it is useful to display a dialog that prompts for a contact's name. Qt provides
						
							QDialog
						
						, which we subclass here to implement a
						
FindDialog
						
						类。
						
					
					
						In order to subclass
						
							QDialog
						
						, we first include the header for
						
							QDialog
						
						在
						
finddialog.h
						
						file. Also, we use forward declaration to declare
						
							QLineEdit
						
						and
						
							QPushButton
						
						since we will be using those widgets in our dialog class.
					
						As in our
						
AddressBook
						
						class, the
						
FindDialog
						
						类包括
						
							Q_OBJECT
						
						macro and its constructor is defined to accept a parent
						
							QWidget
						
						, even though the dialog will be opened as a separate window.
					
#include <QDialog> class QLineEdit; class QPushButton; class FindDialog : public QDialog { Q_OBJECT public: FindDialog(QWidget *parent = nullptr); QString getFindText(); public slots: void findClicked(); private: QPushButton *findButton; QLineEdit *lineEdit; QString findText; };
						We define a public function,
						
getFindText()
						
						, to be used by classes that instantiate
						
FindDialog
						
						. This function allows these classes to obtain the search string entered by the user. A public slot,
						
findClicked()
						
						, is also defined to handle the search string when the user clicks the
						
							Find
						
						button.
					
						Lastly, we define the private variables,
						
findButton
						
						,
						
lineEdit
						
						and
						
findText
						
						, corresponding to the
						
							Find
						
						button, the line edit into which the user types the search string, and an internal string used to store the search string for later use.
						
					
						Within the constructor of
						
FindDialog
						
						, we set up the private variables,
						
lineEdit
						
						,
						
findButton
						
						and
						
findText
						
						. We use a
						
							QHBoxLayout
						
						to position the 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, &QPushButton::clicked, this, &FindDialog::findClicked); connect(findButton, &QPushButton::clicked, this, &FindDialog::accept); }
						We set the layout and window title, as well as connect the signals to their respective slots. Notice that
						
findButton
						
						's
						
							clicked()
						
						signal is connected to
						
findClicked()
						
						and
						
							accept()
						
						。
						
							accept()
						
						slot provided by
						
							QDialog
						
						hides the dialog and sets the result code to
						
							接受
						
						. We use this function to help
						
AddressBook
						
						's
						
findContact()
						
						function know when the
						
FindDialog
						
						object has been closed. We will explain this logic in further detail when discussing the
						
findContact()
						
						函数。
					
					
						在
						
findClicked()
						
						, we validate
						
lineEdit
						
						to ensure that the user did not click the
						
							Find
						
						button without entering a contact's name. Then, we set
						
findText
						
						to the search string, extracted from
						
lineEdit
						
						. After that, we clear the contents of
						
lineEdit
						
						and hide the dialog.
					
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(); } }
						The
						
findText
						
						variable has a public getter function,
						
getFindText()
						
						, associated with it. Since we only ever set
						
findText
						
						directly in both the constructor and in the
						
findClicked()
						
						function, we do not create a setter function to accompany
						
getFindText()
						
						. Because
						
getFindText()
						
						is public, classes instantiating and using
						
FindDialog
						
						can always access the search string that the user has entered and accepted.
					
QString FindDialog::getFindText() { return findText; }
						To ensure we can use
						
FindDialog
						
						from within our
						
AddressBook
						
						class, we include
						
finddialog.h
						
						在
						
addressbook.h
						
						文件。
					
#include "finddialog.h"
					
					
						So far, all our address book features have a
						
							QPushButton
						
						and a corresponding slot. Similarly, for the
						
							Find
						
						feature we have
						
findButton
						
						and
						
findContact()
						
						.
					
						The
						
findButton
						
						is declared as a private variable and the
						
findContact()
						
						function is declared as a public slot.
					
    void findContact();
    ...
    QPushButton *findButton;
					
					
						Lastly, we declare the private variable,
						
dialog
						
						, which we will use to refer to an instance of
						
FindDialog
						
						.
					
    FindDialog *dialog;
					
					Once we have instantiated a dialog, we will want to use it more than once; using a private variable allows us to refer to it from more than one place in the class.
						在
						
AddressBook
						
						class's constructor, we instantiate our private objects,
						
findButton
						
						and
						
findDialog
						
						:
					
    findButton = new QPushButton(tr("&Find"));
    findButton->setEnabled(false);
    ...
    dialog = new FindDialog(this);
					
					
						Next, we connect the
						
findButton
						
						's
						
							clicked()
						
						signal to
						
findContact()
						
						.
					
    connect(findButton, &QPushButton::clicked,
            this, &AddressBook::findContact);
					
					
						Now all that is left is the code for our
						
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); }
						We start out by displaying the
						
FindDialog
						
						instance,
						
dialog
						
						. This is when the user enters a contact name to look up. Once the user clicks the dialog's
						
findButton
						
						, the dialog is hidden and the result code is set to
						
							QDialog::Accepted
						
						. This ensures that our
						
if
						
						statement is always true.
					
						We then proceed to extract the search string, which in this case is
						
contactName
						
						,使用
						
FindDialog
						
						's
						
getFindText()
						
						function. If the contact exists in our address book, we display it immediately. Otherwise, we display the
						
							QMessageBox
						
						shown below to indicate that their search failed.