.tutorials/tutorial/t10/cannonfield.h
.tutorials/tutorial/t10/lcdrange.cpp
.tutorials/tutorial/t10/lcdrange.h
.tutorials/tutorial/t10/main.cpp
.tutorials/tutorial/t10/t10.pro
在這個範例中,我們加入了力量(force)控制。
Line by Line Walkthrough
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.cpp
CannonField::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)); }
我們像第九章一樣畫出來。
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.cpp
MyWidget::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);
在第九章,我們把 angle 放在版面配置的左下那格。現在我們想要讓兩個元件放在同一格裡,所以我們做了一個直的盒子(vertical box),把直的盒子放在網格中,並把 angle 與 range 元件放在直的盒子裡。
force->setValue(25);
我們將力量值初始為 25。
Running the Application
我們現在有力量控制了。
Exercises
使加農砲的砲管大小依據力量值變化。
把加農砲放在右下角。
試著加入更好的鍵盤介面。例如,讓 + 和 - 來增加和減少力量值,並使用 enter 發射。假如你對左方向鍵和右方向鍵的運作方式感到苦惱,也把它改掉吧。[提示:重新實現 QWidget::keyPressEvent()。]
來源:Qt Tutorial 10 - Smooth as Silk
版本:4.4.3
0 回覆:
張貼留言