Qt 5.6 | Qt Widgets | SIP Dialog Example

Qt 5.6.3 Reference Documentation

# SIP Dialog Example

Sometimes it is necessary for a dialog to take the SIP into account, as the SIP may hide important input widgets. The SIP Dialog Example shows how a `Dialog` object, `dialog`, can be resized accordingly if the SIP is opened, by embedding the contents of `dialog` in a QScrollArea.

## Dialog Class Definition

The `Dialog` class is a subclass of QDialog that implements a public slot, `desktopResized()`, and a public function, `reactToSIP()`. Also, it holds a private instance of QRect, `desktopGeometry`.

      class Dialog : public QDialog
      {
          Q_OBJECT

      public:
          Dialog();
          void reactToSIP();

      private:
          QRect desktopGeometry;

      public slots:
          void desktopResized(int screen);
      };

## Dialog Class Implementation

In the constructor of `Dialog`, we start by obtaining the available geometry of the screen with availableGeometry(). The parameter used is `0` to indicate that we require the primary screen.

      Dialog::Dialog()
      {
          desktopGeometry = QApplication::desktop()->availableGeometry(0);

          setWindowTitle(tr("SIP Dialog Example"));
          QScrollArea *scrollArea = new QScrollArea(this);
          QGroupBox *groupBox = new QGroupBox(scrollArea);
          groupBox->setTitle(tr("SIP Dialog Example"));
          QGridLayout *gridLayout = new QGridLayout(groupBox);
          groupBox->setLayout(gridLayout);

We set the window's title to "SIP Dialog Example" and declare a QScrollArea object, `scrollArea`. Next we instantiate a QGroupBox, `groupBox`, with `scrollArea` as its parent. The title of `groupBox` is also set to "SIP Dialog Example". A QGridLayout object, `gridLayout`, is then used as `groupBox`'s layout.

We create a QLineEdit, a QLabel and a QPushButton and we set the minimumWidth property to 220 pixels, respectively.

          QLineEdit* lineEdit = new QLineEdit(groupBox);
          lineEdit->setText(tr("Open and close the SIP"));
          lineEdit->setMinimumWidth(220);

          QLabel* label = new QLabel(groupBox);
          label->setText(tr("This dialog resizes if the SIP is opened"));
          label->setMinimumWidth(220);

          QPushButton* button = new QPushButton(groupBox);
          button->setText(tr("Close Dialog"));
          button->setMinimumWidth(220);

Also, all three widgets' text are set accordingly. The verticalSpacing property of `gridLayout` is set based on the height of `desktopGeometry`. This is to adapt to the different form factors of Windows Mobile. Then, we add our widgets to the layout.

          if (desktopGeometry.height() < 400)
              gridLayout->setVerticalSpacing(80);
          else
              gridLayout->setVerticalSpacing(150);

          gridLayout->addWidget(label);
          gridLayout->addWidget(lineEdit);
          gridLayout->addWidget(button);

The `scrollArea`'s widget is set to `groupBox`. We use a QHBoxLayout object, `layout`, to contain `scrollArea`. The `Dialog`'s layout is set to `layout` and the scroll area's horizontal scroll bar is turned off.

          scrollArea->setWidget(groupBox);
          QHBoxLayout* layout = new QHBoxLayout();
          layout->addWidget(scrollArea);
          setLayout(layout);
          scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

The following signals are connected to their respective slots:

- `button`'s pressed() signal to QApplication's closeAllWindows() slot,
- QDesktopWidget's workAreaResized() signal to `dialog`'s `desktopResized()` slot.

          connect(button, &QAbstractButton::clicked, qApp, &QApplication::closeAllWindows);
          connect(QApplication::desktop(), &QDesktopWidget::workAreaResized,
              this, &Dialog::desktopResized);
      }

The `desktopResized()` function accepts an integer, screen, corresponding to the screen's index. We only invoke `reactToSIP()` if screen is the primary screen (e.g. index = 0).

      void Dialog::desktopResized(int screen)
      {
          if (screen != 0)
              return;
          reactToSIP();
      }

The `reactToSIP()` function resizes `dialog` accordingly if the desktop's available geometry changed vertically, as this change signifies that the SIP may have been opened or closed.

      void Dialog::reactToSIP()
      {
          QRect availableGeometry = QApplication::desktop()->availableGeometry(0);

          if (desktopGeometry != availableGeometry) {
              if (windowState() | Qt::WindowMaximized)
                  setWindowState(windowState() & ~Qt::WindowMaximized);

              setGeometry(availableGeometry);
          }

          desktopGeometry = availableGeometry;
      }

If the height has decreased, we unset the maximized window state. Otherwise, we set the maximized window state. Lastly, we update `desktopGeometry` to the desktop's available geometry.

## The `main()` function

The `main()` function for the SIP Dialog example instantiates `Dialog` and invokes its exec() function.

      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          Dialog dialog;
          return dialog.exec();
      }

Note: Although this example uses a dialog, the techniques used here apply to all top-level widgets respectively.

Files:

- dialogs/sipdialog/dialog.cpp
- dialogs/sipdialog/dialog.h
- dialogs/sipdialog/main.cpp
- dialogs/sipdialog/sipdialog.pro