Модальные окна

Модальным называется окно, которое не позволяет взаимодействовать с другими окнами в том же приложении. Пока модальное окно не будет закрыто, сделать активным другое окно нельзя. Например, если в программе Microsoft Word выбрать пункт меню Файл | Сохранить как, то откроется модальное диалоговое окно, позволяющее выбрать путь и название файла. Пока это окно не будет закрыто, вы не сможете взаимодействовать с главным окном приложения.

Указать, что окно является модальным, позволяет метод setWindowModality() из класса QWidget. Прототип метода:

void setWindowModality(Qt::WindowModality windowModality)

В качестве параметра могут быть указаны следующие константы:

  • Qt::NonModal — окно не является модальным;
  • Qt::WindowModal — окно блокирует только родительские окна в пределах иерархии;
  • Qt::ApplicationModal — окно блокирует все окна в приложении.

Окна, открытые из модального окна, не блокируются. Следует также учитывать, что метод setWindowModality() должен быть вызван до отображения окна.

Получить текущее значение позволяет метод windowModality(). Проверить, является ли окно модальным, можно с помощью метода isModal(). Метод возвращает true, если окно является модальным, и false — в противном случае. Прототипы методов:

Qt::WindowModality windowModality() const
bool isModal() const

Создадим два независимых окна. В первом окне разместим кнопку, при нажатии которой откроем модальное окно. Это модальное окно будет блокировать только первое окно, но не второе. При открытии модального окна отобразим его примерно по центру родительского окна. Содержимое файла widget.h приведено в листинге 3.6, файла widget.cpp — в листинге 3.7, а файла main.cpp — в листинге 3.8.

Листинг 3.6. Содержимое файла widget.h

#include <QPushButton>
#include <QVBoxLayout>

class Widget : public QWidget
{
   Q_OBJECT

public:
   Widget(QWidget *parent=nullptr);
   ~Widget();
private slots:
   void on_btn1_clicked();
private:
   QPushButton *btn1;
   QVBoxLayout *vbox;
};
#endif // WIDGET_H

Листинг 3.7. Содержимое файла widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
   : QWidget(parent)
{
   btn1 = new QPushButton("Открыть модальное окно");
   vbox = new QVBoxLayout();
   vbox->addWidget(btn1);
   setLayout(vbox);
   connect(btn1, SIGNAL(clicked()),
           this, SLOT(on_btn1_clicked()));
}

void Widget::on_btn1_clicked()
{
   QWidget *w = new QWidget(this, Qt::Window);
   w->setWindowTitle("Модальное окно");
   w->resize(300, 50);
   w->setWindowModality(Qt::WindowModal);
   w->setAttribute(Qt::WA_DeleteOnClose, true);
   w->move(frameGeometry().center() - w->rect().center());
   w->show();
}

Widget::~Widget() {}

Листинг 3.8. Содержимое файла main.cpp

#include "widget.h"

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);

   Widget window;
   window.setWindowTitle("Обычное окно");
   window.resize(350, 100);
   window.show();

   QWidget window2;
   window2.setWindowTitle(
              "Это окно не будет блокировано при WindowModal");
   window2.resize(500, 100);
   window2.show();
   return app.exec();
}

Если запустить приложение и нажать кнопку Открыть модальное окно, то откроется окно, выровненное примерно (произвести точное выравнивание вы сможете самостоятельно) по центру родительского окна. При этом получить доступ к родительскому окну можно только при закрытии модального окна, а второе окно блокировано не будет. Если заменить константу Qt::WindowModal константой Qt::ApplicationModal, то оба окна будут блокированы.

Обратите внимание на то, что в конструктор модального окна мы передали указатель на первое окно и константу Qt::Window. Если указатель не передать, то окно блокировано не будет, а если константу не указать, то окно вообще не откроется. Чтобы объект окна автоматически удалялся при закрытии окна константе Qt::WA_DeleteOnClose в методе setAttribute() было присвоено значение true.

Модальные окна в большинстве случаев являются диалоговыми. Для работы с диалоговыми окнами в Qt предназначен класс QDialog, который автоматически выравнивает окно по центру экрана или по центру родительского окна. Кроме того, этот класс предоставляет множество специальных методов, позволяющих дождаться закрытия окна, определить статус завершения и многое другое. Подробно класс QDialog мы будем изучать в отдельной главе.

Учебник C++ (Qt Creator и MinGW)
Учебник C++ (Qt Creator и MinGW) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов