[Предыдущий: Урок 9] [Учебное пособие] [Следующий: Урок 11] Урок 10 - Гладкий как шелк
Файлы:
В этом примере мы добавим контроль силы выстрела. Разберем программу строка за строкойt10/cannonfield.hВ дополнение к углу возвышения CannonField содержит теперь и значение силы выстрела. 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); Интерфейс к силе выстрела следует той же практике, что и для угла возвышения. private: QRect cannonRect() const; Мы поместили определение ограждающего прямоугольника пушки в отдельную функцию. int currentAngle; int currentForce; }; Сила выстрела запоминается в переменной currentForce. t10/cannonfield.cppCannonField::CannonField(QWidget *parent) : QWidget(parent) { currentAngle = 45; currentForce = 0; setPalette(QPalette(QColor(250, 250, 200))); setAutoFillBackground(true); } Сила выстрела инициализируется нулем. 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); } Мы внесли незначительные изменения в функцию setAngle(). Она перерисовывает только ту часть виджета, в которой находится пушка. void CannonField::setForce(int force) { if (force < 0) force = 0; if (currentForce == force) return; currentForce = force; emit forceChanged(currentForce); } Реализация функции setForce() довольно похожа на таковую для setAngle(). Единственная разница заключается в том, что поскольку значение силы выстрела мы не показываем, то перерисовывать виджет нам не нужно. 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));
}
Рисуем как в Уроке 9. QRect CannonField::cannonRect() const { QRect result(0, 0, 50, 50); result.moveBottomLeft(rect().bottomLeft()); return result; } Функция cannonRect() возвращает ограждающий прямоугольник пушки в координатах виджета. Сначала мы создаем прямоугольник с размерами 50 x 50, а затем передвигаем его так, чтобы его нижний левый угол совпадал с нижним левым углом виджета. Функция QWidget::rect() возвращает ограничивающий прямоугольник виджета в координатах виджета. Верхний левый угол прямоугольника всегда имеет координаты (0, 0). t10/main.cppMyWidget::MyWidget(QWidget *parent) : QWidget(parent) { Конструктор по большей части тот же, но были добавлены несколько кусочков. LCDRange *force = new LCDRange; force->setRange(10, 50); Мы добавили второй ЖК-индикатор LCDRange, который будет использоваться для установки силы выстрела. connect(force, SIGNAL(valueChanged(int)), cannonField, SLOT(setForce(int))); connect(cannonField, SIGNAL(forceChanged(int)), force, SLOT(setValue(int))); Мы соединили виджет force и виджет cannonField так же, как сделали для виджета angle. QVBoxLayout *leftLayout = new QVBoxLayout; leftLayout->addWidget(angle); leftLayout->addWidget(force); QGridLayout *gridLayout = new QGridLayout; gridLayout->addWidget(quit, 0, 0); gridLayout->addLayout(leftLayout, 1, 0); gridLayout->addWidget(cannonField, 1, 1, 2, 1); gridLayout->setColumnStretch(1, 10); В Уроке 9 мы поместили виджет angle в нижнюю левую ячейку компоновки. Теперь мы хотим иметь два виджета в ячейке, поэтому мы сделали вертикальный прямоугольник, поместили его в ячейку сетки и поместили angle и range в этот прямоугольник. force->setValue(25); Инициализируем силу выстрела значением 25. Запуск приложенияТеперь мы имеет контроль силы выстрела. Домашнее заданиеСделайте размер ствола пушки зависящим от силы выстрела. Поместите пушку в нижний правый угол. Попытайтесь добавить улучшенный клавиатурный интерфейс. Например, сделайте увеличение и уменьшение силы выстрела с помощью клавиш + и -, а с помощью клавиши enter - выстрел. Если вас не устраивает способ работы клавиш Left и Right, то измените также и его. [Подсказка: Реализуйте заново QWidget::keyPressEvent().] [Предыдущий: Урок 9] [Учебное пособие] [Следующий: Урок 11]
|
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |