Subclassing QDialog

//findDlg.h

#ifndef FINDDLG_H

#define FINDDLG_H

 

// includes the definition of QDialog , the base class for dialogs in Qt. QDialog is derived from QWidget

#include <QDialog>

 

//A forward declaration tells the C++ compiler that a class exists, without giving all the detail that a class definition (usually located in a //header  file of its own) provides.

class QLabel;

class QLineEdit;

class QPushButton;

class QCheckBox;

 

class FindDlg : public QDialog

{

//The Q_OBJECT macro at the beginning of the class definition is necessary for all classes that define signals or slots

    Q_OBJECT

 

public:

    FindDlg( QWidget *parent = 0 );

 

//The signals keyword is actually a macro. The C++ preprocessor converts it into standard C++ before the compiler sees it.

signals:

//Qt::CaseSensitivity is an enum type that can take the values Qt::CaseSensitive and Qt::CaseInsensitive .

    void findNext( const QString &str, Qt::CaseSensitivity cs );

    void findPrevious( const QString &str, Qt::CaseSensitivity  cs );


private slots:

    void findClicked();

    void enableFindBtn( const QString &text );


private:

    QLabel *label;

    QLineEdit *lineEdit;

    QCheckBox *backwardCheckBox;

    QCheckBox *caseCheckBox;

    QPushButton *findBtn;

    QPushButton *closeBtn;

};

 

#endif

 

 

//findDlg.cpp

#include <QtGui>

#include "findDlg.h"

 

FindDlg::FindDlg(QWidget *parent)
: QDialog(parent)
{
//The tr() function calls around the string literals mark them for translation to other languages
//we use ampersands ('&') to indicate shortcut keys
label = new QLabel(tr("Find &what:"));
lineEdit = new QLineEdit;
// A buddy is a widget that accepts the focus when the label's shortcut key is pressed.
//So when the user presses Alt+W (the label's shortcut), the focus goes to the line editor (the label's buddy).
label->setBuddy(lineEdit);

caseCheckBox = new QCheckBox(tr("Match &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward"));

findBtn = new QPushButton(tr("&Find"));
findBtn->setDefault(true);
findBtn->setEnabled(false);

closeBtn = new QPushButton(tr("Close"));

connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableFindBtn(const QString &)));
connect(findBtn, SIGNAL(clicked()),
this, SLOT(findClicked()));
connect(closeBtn, SIGNAL(clicked()),
this, SLOT(close()));

QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);

QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox);

QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();

QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);

setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
QString text = lineEdit->text();
Qt::CaseSensitivity cs =
caseCheckBox->isChecked() ? Qt::CaseSensitive
: Qt::CaseInsensitive;
if (backwardCheckBox->isChecked()) {
emit findPrevious(text, cs);
} else {
emit findNext(text, cs);
}

}

void FindDialog::enableFindButton(const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}

//main.cpp
#include <QApplication>

#include "finddialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}


NOTE:
For moc to work correctly, we must
put the class definition in a header file, separate from the
implementation file. The code generated by moc includes this header file and adds some C++ boilerplate code of its own.

Classes that use the Q_OBJECT macro must have moc run on them. This isn't a problem because qmake automatically adds the necessary rules to the makefile. But if you forget to regenerate your makefile using qmake and moc
isn't run, the linker will complain that some functions are declared
but not implemented. The messages can be fairly obscure. GCC produces
error messages like this one:
finddialog.o: In function `FindDialog::tr(char const*, char const*)':
/usr/lib/qt/src/corelib/global/qglobal.h:1430: undefined reference to
`FindDialog::staticMetaObject'

If this ever happens to you, run qmake again to update the makefile, then rebuild the application.

 

Now run the program. If shortcut keys are shown on your platform, verify that the shortcut keys Alt+W , Alt+C , Alt+B , and Alt+F trigger the correct behavior. Press Tab to navigate through the widgets with the keyboard. The default tab order is the order in which the widgets were created. This can be changed using QWidget::setTabOrder() .

 

Providing a sensible tab order and keyboard shortcuts ensures that users who don't want to (or cannot) use a mouse are able to make full use of the application. Full keyboard control is also appreciated by fast typists.

你可能感兴趣的:(Subclassing QDialog)