Linux 版 (精华区)

发信人: pilot (〓〓★〓〓), 信区: Linux
标  题: Qt Tutoial 9
发信站: 紫 丁 香 (Thu May 18 19:45:30 2000), 转信

被cliff严重打击了积极性,所以今天才想起来翻译第九章.

Subject Qt tutorial -------"With Cannon You Can"
Posted by kensou
Translated by Pilot-=?=-

第九章: With Cannon You Can

在这个例程中我们第一次使用QPainter类,用来画一个小巧的蓝色炮台,与上一章相比
只有cannon.cpp文件有改动(实际上main.cpp也加了一句代码)。

lcdrange.h      LCDRange类定义
/*略*/

lcdrange.cpp    LCDRange类实现文件
/*略*/

cannon.         CannonField类定义
/*略*/

cannon.cpp      CannonField类实现文件
/****************************************************************
**
** Implementation CannonField class, Qt tutorial 9
**
****************************************************************/
#include "cannon.h"
#include <qpainter.h>
CannonField::CannonField( QWidget *parent, const char *name )
: QWidget( parent, name )
{
    ang = 45;
}
void CannonField::setAngle( int degrees )
{
    if ( degrees < 5 )
        degrees = 5;
    if ( degrees > 70 )
        degrees = 70;
    if ( ang == degrees )
        return;
    ang = degrees;
    repaint();
    emit angleChanged( ang );
}
void CannonField::paintEvent( QPaintEvent * )
{
    QPainter p;
    QBrush   brush( blue );
    QPen     pen( NoPen );
    p.begin( this );
    p.setBrush( brush );
    p.setPen( pen );
    p.translate( 0, rect().bottom() );
    p.drawPie( QRect(-35, -35, 70, 70), 0, 90*16 );
    p.rotate( -ang );
    p.drawRect( QRect(33, -4, 15, 8) );
    p.end();
}

main.cpp        包含MyWidget类及main函数
/****************************************************************
**
** Qt tutorial 9
**
****************************************************************/
#include <qapplication.h>
#include <qpushbutton.h>
#include <qscrollbar.h>
#include <qlcdnumber.h>
#include <qfont.h>
#include "lcdrange.h"
#include "cannon.h"
class MyWidget : public QWidget
{
    public:
        MyWidget( QWidget *parent=0, const char *name=0 );

    protected:
        void resizeEvent( QResizeEvent * );

    private:
        QPushButton *quit;
        LCDRange    *angle;
        CannonField *cannonField;
};
MyWidget::MyWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
    setMinimumSize( 500, 355 );
    quit = new QPushButton( "Quit", this, "quit" );
    quit->setGeometry( 10, 10, 75, 30 );
    quit->setFont( QFont( "Times", 18, QFont::Bold ) );
    connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
    angle  = new LCDRange( this, "angle" );
    angle->setRange( 5, 70 );
    angle->setGeometry( 10, quit->y() + quit->height() + 10, 75, 130 );
    cannonField = new CannonField( this, "cannonField" );
    cannonField->move( angle->x() + angle->width() + 10, angle->y() );
    cannonField->setBackgroundColor( QColor( 250, 250, 200) );
    connect( angle,SIGNAL(valueChanged(int)), cannonField,SLOT(setAngle(int)));
    connect( cannonField,SIGNAL(angleChanged(int)), angle,SLOT(setValue(int)));
    angle->setValue( 60 );
}
void MyWidget::resizeEvent( QResizeEvent * )
{
    cannonField->resize( width()  - cannonField->x() - 10,
                         height() - cannonField->y() - 10 );
}
int main( int argc, char **argv )
{
    QApplication::setColorSpec( QApplication::CustomColor );
    QApplication a( argc, argv );
    MyWidget w;
    w.setGeometry( 100, 100, 500, 355 );
    a.setMainWidget( &w );
    w.show();
    return a.exec();
}

Makefile        Make文件,包含了支持signal/slot的内容
/*略*/

逐行解释

cannon.cpp
void CannonField::paintEvent( QPaintEvent * )
{
    QPainter p;
    QBrush   brush( blue );
    QPen     pen( NoPen );
为了画我们的组件,我们使用了QPainter. 一个可以在各类绘图设备(paint devices)
上图画2D图形的Qt绘图引擎.QWidget就是一种绘图设备,详细介绍参见Qt文档.
QPainter使用QPen,QBrush绘图.当brush指定填充色以及(或者)填充风格时pen是以文
本颜色画线的工具.在我们的重画事件处理函数中,我们需要一个蓝色的刷(brush)和一
个不可见的笔(pen).
p.begin( this );
调用begin()在绘图设备上开始绘图,这里的绘图设备是CannonField组件.
p.setBrush( brush );
p.setPen( pen );
创建我们的刷和笔.
p.translate( 0, rect().bottom() );
translate()通过使用偏移量来转变QPainter的坐标系统,这里我们设置组件的左下角为
(0,0)坐标.x,y轴的方向不变.也就是说组件区域中的y坐标值都为负(参见The Coordinate
System坐标系统).
p.drawPie( QRect(-35, -35, 70, 70), 0, 90*16 );
drawPie()函数通过指定起始角和弧长在特定的矩形内画饼型图案.角度值单位为1/16度.
零度在三点钟位置,绘图方向为逆时针.这里我们在组件左下角画了一个四分之一圆,
蓝色填充,没有边框.
p.rotate( -ang );
rorate()函数统过指定旋转角度(浮点数,单位为度)来围绕(0,0)旋转QPainter的坐标系
统,顺时针.这里我们旋转组件-ang度,也就是逆时针旋转组件ang度.
p.drawRect( QRect(33, -4, 15, 8) );
drawRect()函数画指定的矩形区域,这里用来画炮管.
很难想象在一个转变过的(偏移,旋转,缩放,剪切)坐标系统中画出的矩形是什么样子.
刚开始矩形QRect(33, -4, 15, 8)是这个样子:
/*一个炮口水平指向右方的小炮台*/
注意这个矩形(炮管)被CannonField组件的边框挡住一部分.
当我们旋转坐标系统时,比如说60度,这个矩形围绕(0,0)旋转,于是变成了下面这个样
子:
/*一个炮口指向右上方的小炮台*/
p.end();
调用end()结束绘画操作.
int main( int argc, char **argv )
{
    QApplication::setColorSpec( QApplication::CustomColor );
这里我们设置了一个与原来不同的色彩分配策略(color allocation strategy),没有通
用的策略,某些策略在某些程序里看起来很不错,可能另外一些策略看起来就很糟糕.
CustomColor可以使Qt程序有一个不错的窗口颜色,但在X11下无效.还有别的色彩分配策
略选项,参见文档.
(color allocation strategy好像是用来在不同X色彩设置下改善窗口色彩用的,有Normal
Color,CustomColor,ManyColor,不大明白到底是什么东西.)

程序行为

当用户操作滚动条时,炮的指向也同时变化.
你会发现炮的图案在不停闪动,特别是在低档的机器上,下一章解决这个问题.

练习

设置CannonField组件的背景像素映射(pixmap,不懂这里是什么意思).

你现在可以进入第十章了.

--


               〓〓★〓〓

        比别人飞的更高,更快,更强!

※ 修改:.pilot 于 May 18 19:55:09 修改本文.[FROM: mtlab2.hit.edu.c]
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab2.hit.edu.c]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:6.694毫秒