Создание собственного диалогового окна


Оглавление

Программа, показанная на рисунке, является результатом создания собственного диалогового окна. При запуске на экране окно с кнопкой Press Me (Нажми меня), нажатие на которую отображает диалоговое окно ввода имени First Name (Имя) и фамилии Last Name (Фамилия).


// Файл main.cpp
#include <QApplication>
#include "StartDialog.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    StartDialog  startDialog;
    
    startDialog.setMinimumWidth(200);
    startDialog.show();

    return app.exec();
}

В файле main.cpp создается виджет класса StartDialog, предназначенный для запуска диалогового окна.

Создание собственного диалогового окна


// Файл StartDialog.h
#ifndef _StartDialog_h_
#define _StartDialog_h_

#include <QtGui>
#include "InputDialog.h"

class StartDialog : public QPushButton {
Q_OBJECT
public:
    StartDialog(QWidget* pwgt = 0) : QPushButton("Press Me", pwgt) 
    {
        connect(this, SIGNAL(clicked()), SLOT(slotButtonClicked()));
    }

public slots:
    void slotButtonClicked()
    {
        InputDialog* pInputDialog = new InputDialog;    
        if (pInputDialog->exec() == QDialog::Accepted) {
            QMessageBox::information(0, 
                                     "Information", 
                                     "First Name: " 
                                     + pInputDialog->firstName()
                                     + "\nLast Name: " 
                                     + pInputDialog->lastName()
                                    );
        }
        delete pInputDialog;
    } 
};
#endif  //_StartDialog_h_

Класс StartDialog унаследован от класса кнопки нажатия. Сигнал clicked() соединяется в методе connect() со слотом slotButtonClicked(). В этом слоте создается объект диалогового окна InputDialog, который не имеет предка.

Примечание: Диалоговые окна, не имеющее предка, будут центрироваться по экрану. Окна с предками будут отцентрированы относительно предка.

В операторе if производится запуск диалогового окна. После его закрытия управление передается основной программе и метод exec() возвращает значение нажатой пользователем кнопки. В том случае, если пользователем была нажата кнопка Ok, произойдет отображение информационного окна с введенными в диалоговом окне данными. По завершении метода диалоговое окно нужно удалить самому, так как у него нет предка, который позаботится об этом.


// Файл  InputDialog.h
#ifndef _InputDialog_h_
#define _InputDialog_h_

#include <QDialog>

class QLineEdit;
class InputDialog : public QDialog {
    Q_OBJECT
private:
    QLineEdit* m_ptxtFirstName;
    QLineEdit* m_ptxtLastName;

public:
    InputDialog(QWidget* pwgt = 0);

    QString firstName() const;
    QString lastName () const;
};
#endif  //_InputDialog_h_

Для создания своего собственного диалогового окна нужно унаследовать класс QDialog. Класс InputDialog содержит два атрибута — указатели m_ptxtFirstName и m_ptxtLastName на виджеты однострочного текстового поля, и два метода, возвращающие содержимое этих полей — firstName() и lastName().


//  Файл InputDialog.cpp
#include <QtGui>
#include "InputDialog.h"

InputDialog::InputDialog(QWidget* pwgt/*= 0*/) 
     : QDialog(pwgt, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
{   
    m_ptxtFirstName = new QLineEdit;
    m_ptxtLastName  = new QLineEdit;

    QLabel* plblFirstName    = new QLabel("&First Name");
    QLabel* plblLastName     = new QLabel("&Last Name");

    plblFirstName->setBuddy(m_ptxtFirstName);
    plblLastName->setBuddy(m_ptxtLastName);

    QPushButton* pcmdOk     = new QPushButton("&Ok");
    QPushButton* pcmdCancel = new QPushButton("&Cancel");

    connect(pcmdOk, SIGNAL(clicked()), SLOT(accept()));
    connect(pcmdCancel, SIGNAL(clicked()), SLOT(reject()));

    //Layout setup
    QGridLayout* ptopLayout = new QGridLayout;
    ptopLayout->addWidget(plblFirstName, 0, 0);
    ptopLayout->addWidget(plblLastName, 1, 0);
    ptopLayout->addWidget(m_ptxtFirstName, 0, 1);
    ptopLayout->addWidget(m_ptxtLastName, 1, 1);
    ptopLayout->addWidget(pcmdOk, 2,0);
    ptopLayout->addWidget(pcmdCancel, 2, 1);
    setLayout(ptopLayout);
}

По умолчанию область заголовка диалогового окна содержит кнопку ?, служащую для получения подробной информации о назначении виджетов.

В нашем примере я решил пренебречь ею — для этого необходимо установить флаги окна, поэтому вторым параметром передаются флаги Qt::WindowTitleHint и Qt::WindowSystemMenuHint, первый устанавливает заголовок окна, а второй — добавляет системное меню с возможностью закрытия окна.

Модальное диалоговое окно всегда должно содержать кнопку Cancel (Отмена). Сигналы clicked() кнопок Ok и Cancel (Отмена) соединяются со слотами accept() и rejected() соответственно. Это делается для того, чтобы метод exec() возвращал при нажатии кнопки Ok значение QDialog::Accepted, а при нажатии на кнопку Cancel (Отмена) — значение QDialog::Rejected.


QString InputDialog::firstName() const 
{ 
    return m_ptxtFirstName->text(); 
}

Метод firstName() возвращает введенное пользователем имя:


QString InputDialog::lastName() const 
{ 
    return m_ptxtLastNanie->text (); 
}

Метод lastName() возвращает введенную пользователем фамилию.

Создание стандартных диалоговых окон