- Qt 5.5
- Qt Widgets
- SIP Dialog Example
- Qt 5.5.1 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, SIGNAL(clicked()),
            qApp, SLOT(closeAllWindows()));
        connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
            this, SLOT(desktopResized(int)));
    }

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