Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

[Previous: Chapter 5] [Qt Tutorial] [Next: Chapter 7]

# Qt Tutorial 6 - Building Blocks Galore!

Files:

- tutorial/t6/main.cpp

This example shows how to encapsulate two widgets into a new component and how easy it is to use many widgets. For the first time, we use a custom widget as a child widget.

        /****************************************************************
        **
        ** Qt tutorial 6
        **
        ****************************************************************/

        #include <QApplication>
        #include <QFont>
        #include <QGridWidget>
        #include <QLCDNumber>
        #include <QPushButton>
        #include <QSlider>
        #include <QVBoxWidget>

        class LCDRange : public QVBoxWidget
        {
        public:
            LCDRange(QWidget *parent = 0);
        };

        LCDRange::LCDRange(QWidget *parent)
            : QVBoxWidget(parent)
        {
            QLCDNumber *lcd = new QLCDNumber(2, this);
            QSlider *slider = new QSlider(Qt::Horizontal, this);
            slider->setRange(0, 99);
            slider->setValue(0);
            connect(slider, SIGNAL(valueChanged(int)),
                    lcd, SLOT(display(int)));
        }

        class MyWidget : public QVBoxWidget
        {
        public:
            MyWidget(QWidget *parent = 0);
        };

        MyWidget::MyWidget(QWidget *parent)
            : QVBoxWidget(parent)
        {
            QPushButton *quit = new QPushButton("Quit", this);
            quit->setFont(QFont("Times", 18, QFont::Bold));

            connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));

            QGridWidget *grid = new QGridWidget(4, this);
            for (int row = 0; row < 4; ++row) {
                for (int column = 0; column < 4; ++column) {
                    (void) new LCDRange(grid);
                }
            }
        }

        int main(int argc, char *argv[])
        {
            QApplication app(argc, argv);
            MyWidget widget;
            app.setMainWidget(&widget);
            widget.show();
            return app.exec();
        }

## Line by Line Walkthrough

        class LCDRange : public QVBoxWidget
        {
        public:
            LCDRange(QWidget *parent = 0);
        };

The `LCDRange` widget is a widget without any API. It just has a constructor. This sort of widget is not very useful, so we'll add some API later.

        LCDRange::LCDRange(QWidget *parent)
            : QVBoxWidget(parent)
        {
            QLCDNumber *lcd = new QLCDNumber(2, this);
            QSlider *slider = new QSlider(Qt::Horizontal, this);
            slider->setRange(0, 99);
            slider->setValue(0);
            connect(slider, SIGNAL(valueChanged(int)),
                    lcd, SLOT(display(int)));
        }

This is lifted straight from the `MyWidget` constructor in Chapter 5. The only differences are that the Quit button is left out and the class is renamed.

        class MyWidget : public QVBoxWidget
        {
        public:
            MyWidget(QWidget *parent = 0);
        };

`MyWidget`, too, contains no API except a constructor.

        MyWidget::MyWidget(QWidget *parent)
            : QVBoxWidget(parent)
        {
            QPushButton *quit = new QPushButton("Quit", this);
            quit->setFont(QFont("Times", 18, QFont::Bold));

            connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));

The push button that used to be in what is now `LCDRange` has been separated so that we can have one Quit button and many `LCDRange` objects.

            QGridWidget *grid = new QGridWidget(4, this);

We create a QGridWidget object with four columns. The QGridWidget automatically arranges its children in rows and columns; you can specify the number of rows or of columns, and QGridWidget will discover its new children and fit them into the grid.

            for (int row = 0; row < 4; ++row) {
                for (int column = 0; column < 4; ++column) {
                    (void) new LCDRange(grid);
                }
            }

We create 16 `LCDRange` widgets, all of which are children of the grid object. The QGridWidget will arrange them in four columns.

        }

That's all.

## Running the Application

This program shows how easy it is to use many widgets at a time. Each one behaves like the slider and LCD number in the previous chapter. Again, the difference lies in the implementation.

## Exercises

Initialize each slider with a different/random value on startup.

The source contains three occurrences of "4". What happens if you change the one in the QGridWidget constructor call? What about the other two? Why is this?

[Previous: Chapter 5] [Qt Tutorial] [Next: Chapter 7]