Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

[Previous: Chapter 9] [Qt Tutorial] [Next: Chapter 11]

# Qt Tutorial 10 - Smooth as Silk

Files:

In this example, we add a force control.

## Line by Line Walkthrough

### t10/cannonfield.h

The CannonField now has a force value in addition to the angle.

```     int angle() const { return currentAngle; }
int force() const { return currentForce; }

public slots:
void setAngle(int angle);
void setForce(int force);

signals:
void angleChanged(int newAngle);
void forceChanged(int newForce);```

The interface to the force follows the same practice as for the angle.

``` private:
QRect cannonRect() const;```

We have put the definition of the cannon's enclosing rectangle in a separate function.

```     int currentAngle;
int currentForce;
};```

The force is stored in the currentForce variable.

### t10/cannonfield.cpp

``` CannonField::CannonField(QWidget *parent)
: QWidget(parent)
{
currentAngle = 45;
currentForce = 0;
setPalette(QPalette(QColor(250, 250, 200)));
setAutoFillBackground(true);
}```

The force is initialized to zero.

``` void CannonField::setAngle(int angle)
{
if (angle < 5)
angle = 5;
if (angle > 70)
angle = 70;
if (currentAngle == angle)
return;
currentAngle = angle;
update(cannonRect());
emit angleChanged(currentAngle);
}```

We have made a slight change in the setAngle() function. It repaints only the portion of the widget that contains the cannon.

``` void CannonField::setForce(int force)
{
if (force < 0)
force = 0;
if (currentForce == force)
return;
currentForce = force;
emit forceChanged(currentForce);
}```

The implementation of setForce() is quite similar to that of setAngle(). The only difference is that because we don't show the force value, we don't need to repaint the widget.

``` void CannonField::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);

painter.setPen(Qt::NoPen);
painter.setBrush(Qt::blue);

painter.translate(0, height());
painter.drawPie(QRect(-35, -35, 70, 70), 0, 90 * 16);
painter.rotate(-currentAngle);
painter.drawRect(QRect(30, -5, 20, 10));
}```

We paint as in Chapter 9.

``` QRect CannonField::cannonRect() const
{
QRect result(0, 0, 50, 50);
result.moveBottomLeft(rect().bottomLeft());
return result;
}```

The cannonRect() function returns the rectangle enclosing the cannon in widget coordinates. First we create a rectangle with the size 50 x 50 and then move it so its bottom-left corner is equal to the widget's own bottom-left corner.

The QWidget::rect() function returns the widget's enclosing rectangle in the widget's own coordinates. The top-left corner of the rectangle is always (0, 0).

### t10/main.cpp

``` MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{```

The constructor is mostly the same, but some new bits have been added.

```     LCDRange *force = new LCDRange;
force->setRange(10, 50);```

We add a second LCDRange, which will be used to set the force.

```     connect(force, SIGNAL(valueChanged(int)),
cannonField, SLOT(setForce(int)));
connect(cannonField, SIGNAL(forceChanged(int)),
force, SLOT(setValue(int)));```

We connect the force widget and the cannonField widget, just like we did for the angle widget.

```     QVBoxLayout *leftLayout = new QVBoxLayout;

QGridLayout *gridLayout = new QGridLayout;
gridLayout->setColumnStretch(1, 10);```

In Chapter 9, we put angle in the lower-left cell of the layout. Now we want to have two widgets in that cell, so we make a vertical box, put the vertical box in the grid cell, and put each of angle and range in the vertical box.

`     force->setValue(25);`

We initialize the force value to 25.

## Running the Application

We now have a force control.

## Exercises

Make the size of the cannon barrel be dependent on the force.

Put the cannon in the bottom-right corner.

Try adding a better keyboard interface. For example, make + and - increase and decrease the force and enter shoot. If you're bothered by the way the Left and Right keys work, change that too. [Hint: Reimplement QWidget::keyPressEvent().]

[Previous: Chapter 9] [Qt Tutorial] [Next: Chapter 11]